添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Android架构模块-数据库框架设计与实现

一、设计目标

1. 对上层提供统一、唯一的接口,不仅支持关系型数据库,还要支持非关系型数据库。

2. 以基于ORM思想,泛型为实现的方法进行数据库操作进行封装。

3. 实现数据库可配置,可替换。

二、框架图

框架核心采用了工厂模式+简单工厂模式,本来应该由BaseDao去实现Query来构成工厂模式,但为了最大程度解耦,在创建Query时又采用了简单工厂去关联IQuery接口。UserDao则是客户端调用者,同样采用简单工厂来与IDataBaseDao关联。IPageModel、ITreeModel则分别是为分页、树形结构服务的。(这里一说到简单工厂,实际上是交由spring的IOC来完成的)最终使得任何类都是基于接口实现,从而达到整体框架灵活性。

三、代码实现

1. IDataBaseDao

package com.core.dao;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
 * 数据库访问操作对象
 * @author Wang
 * @param <T> 实体类
 * @param <PK> 主键类型
public interface IDataBaseDao<T extends Serializable, PK extends Serializable> {
	 * 设置实体类
	 * @param entityClass 实体类class
	void setEntityClass(Class<T> entityClass);
	 * 新建一个查询对象
	 * @return
	IQuery createQuery();
	 * 获取数据
	 * @param id 主键
	 * @return
	T get(PK id);
	 * 加载数据
	 * @param id 主键
	 * @return
	T load(PK id);
	 * 加载全部数据
	 * @return
	List<T> loadAll();
	 * 查询数据
	 * @param query 查询对象
	 * @return
	List<T> find(IQuery query);
	 * 保存数据
	 * @param entity 实体类
	 * @return
	PK save(T entity);
	 * 更新数据
	 * @param entity 实体类
	void update(T entity);
	 * 保存或更新数据
	 * @param entity 实体类
	void saveOrUpdate(T entity);
	 * 保存或更新全部数据
	 * @param entities 实体类集合
	void saveOrUpdateAll(Collection<T> entities);
	 * 删除数据
	 * @param entity 实体类
	void delete(T entity);
	 * 依据主键删除数据
	 * @param id 主键
	void deleteByKey(PK id);
	 * 删除全部数据
	 * @param entities 实体类集合
	void deleteAll(Collection<T> entities);
}

说明: 该接口是本系统数据库框架对外提供服务的核心接口,也是各个数据库实现框架(hibernate、ibatis、)的抽象接口,使本系统不局限于某种数据库实现框架,支持各种常见数据库实现框架。

系统其它框架都要统一调用接口,不可直接调用实现类。

支持泛型,第一个T为返回对象类型,第二个PK为主键类型。

2. IQuery

package com.core.dao;
import java.util.List;
 * 查询操作对象
 * @author Wang
public interface IQuery {
	 * 获取对象查询语句
	 * @return
	String getQueryString();
	 * 获取sql查询语句
	 * @return
	String getSQLString();
	 * 获取查询参数集合
	 * @return
	Object[] getParamValues();
	 * 获取查询数据的起始位号,用于分页
	 * @return
	int getFirstResult();
	 * 获取查询数据的最大长度,用于分页
	 * @return
	int getMaxResults();
	 * 设置表的实体类集合
	 * @param entityClasses 实体类class集合
	@SuppressWarnings("rawtypes")
	void setEntityClass(Class[] entityClasses);
	 * 设置对象查询语句
	 * @param queryStr 对象查询语句字符串
	void setQueryString(String queryStr);
	 * 设置sql查询语句
	 * @param sql sql查询语句字符串
	void setSQLString(String sql);
	 * 设置查询参数集合
	 * @param values 参数值集合
	void setParamValues(Object[] values);
	 * 设置查询数据的起始值,用于分页
	 * @param value 起始值
	void setFirstResult(int value);
	 * 设置查询数据的最大长度,用于分页
	 * @param value 最大值
	void setMaxResults(int value);
	 * 执行查询
	 * @return
	@SuppressWarnings("rawtypes")
	List execute();
}

说明: 该接口是专门针对于查询数据库设计的,不同数据库,其查询语言都不太一样,而增删改操作则都较为简单。任何涉及到查询数据库的操作都要统一采用此接口的方式实现。

提供对原生SQL的支持,即getSQLString、setSQLString,同时该方法并不仅仅用于SQL语句,同样适用于非关系数据库的一些特殊的查询语句(如Mongodb),而getQueryString、setQueryString则是针对面向对象的查询语句而独自提供的方法。

为了防止一些查询语句无法彻底封装,提供了一个excute方法来完成查询。

提供getFirstResult等方法来对分页查询提供支持。

3. IPageModel

package com.core.dao;
import java.io.Serializable;
import java.util.List;
 * 分页操作对象
 * @author Wang
 * @param <T> 数据对象类型
public interface IPageModel<T extends Serializable> {
	 * 获取一页显示多少条数据的值
	 * @return
	int getPageSize();
	 * 获取总页数的值
	 * @return
	int getTotalPages();
	 * 获取当前页号
	 * @return
	int getPageNumber();
	 * 获取该页第一条数据的行号
	 * @return
	int getFirstResult();
	 * 获取该页数据
	 * @return
	List<T> getDataResult();
	 * 是否是首页
	 * @return
	boolean isFirstPage();
	 * 是否是尾页
	 * @return
	boolean isLastPage();
	 * 设置一页显示多少条数据
	 * @param value
	void setPageSize(int value);
	 * 设置总页数
	 * @param value
	void setTotalPages(int value);
	 * 设置当前页号
	 * @param value
	void setPageNumber(int value);
	 * 设置该页第一条数据的行号
	 * @param value
	void setFirstResult(int value);
	 * 设置该页数据
	 * @param data
	void setDataResult(List<T> data);
}

说明:该接口用于分页功能,任何分页的实现都必须用该接口。

4. ITreeModel

package com.core.dao;
import java.io.Serializable;
public interface ITreeModel<PK extends Serializable> {
	PK getNodeId();
	PK getNodePid();
	String getNodeName();
	int getNodeOrder();
	String getNodeImage();
	int getNodeLevel();
	void setNodeId(PK nodeId);
	void setNodePid(PK nodePid);
	void setNodeName(String nodeName);
	void setNodeOrder(PK nodeOrder);
	void setNodeImage(String nodeImage);
	void setNodeLevel(int nodelLevel);
}

说明: 该接口用于树形功能。任何树形的实现都必须用该接口。

5. BaseDao

package com.core.dao.hibernate;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.core.dao.IDataBaseDao;
import com.core.dao.IQuery;
import com.util.BeanUtil;
public class BaseDao<T extends Serializable, PK extends Serializable> implements IDataBaseDao<T, PK> {
	@Resource
	private HibernateTemplate hibernateTemplate;
	@Resource
	private IQuery query;
	private Class<T> entityClass;
	@Override
	public void setEntityClass(Class<T> entityClass) {
		this.entityClass = entityClass;
	@Override
	public IQuery createQuery() {
		return query;
	@SuppressWarnings("unchecked")
	@Override
	public T get(PK id) {
		return (T) hibernateTemplate.get(entityClass, id);
	@SuppressWarnings("unchecked")
	@Override
	public T load(PK id) {
		return (T) hibernateTemplate.load(entityClass, id);
	@SuppressWarnings("unchecked")
	@Override
	public List<T> loadAll() {
		return hibernateTemplate.loadAll(entityClass);
	@SuppressWarnings("unchecked")
	@Override
	public List<T> find(IQuery query) {
		final String queryString = query.getQueryString();
		if (!BeanUtil.isNull(queryString)) {
			final Object[] values = query.getParamValues();
			final int firstResult = query.getFirstResult();
			final int maxResult = query.getMaxResults();
			if (!BeanUtil.isNull(values)) {
				if (maxResult > 0) {
					hibernateTemplate.executeFind(new HibernateCallback() {
						@Override
						public Object doInHibernate(Session session) throws HibernateException, SQLException {
							Query query = session.createQuery(queryString);
							query.setFirstResult(firstResult);
							query.setMaxResults(maxResult);
							for (int i = 0; i < values.length; i++) {
								query.setParameter(i + 1, values[i]);
							return query.list();
				return hibernateTemplate.find(queryString, values);
			} else {
				if (maxResult > 0) {
					hibernateTemplate.executeFind(new HibernateCallback() {
						@Override
						public Object doInHibernate(Session session) throws HibernateException, SQLException {
							Query query = session.createQuery(queryString);
							query.setFirstResult(firstResult);
							query.setMaxResults(maxResult);
							return query.list();
				return hibernateTemplate.find(queryString);
		String sql = query.getSQLString();
		if (!BeanUtil.isNull(sql)) {
			return query.execute();
		} else {
			//  需要抛出异常
			return null;
	@SuppressWarnings("unchecked")
	@Override
	public PK save(T entity) {
		return (PK) hibernateTemplate.save(entity);
	@Override
	public void update(T entity) {
		hibernateTemplate.update(entity);
	@Override
	public void saveOrUpdate(T entity) {
		hibernateTemplate.saveOrUpdate(entity);
	@Override
	public void saveOrUpdateAll(Collection<T> entities) {
		hibernateTemplate.saveOrUpdateAll(entities);
	@Override
	public void delete(T entity) {
		hibernateTemplate.delete(entity);
	@Override
	public void deleteByKey(PK id) {
		T t = this.get(id);
		hibernateTemplate.delete(t);
	@Override
	public void deleteAll(Collection<T> entities) {
		hibernateTemplate.deleteAll(entities);
}

说明: 该类是对IDataBaseDao的实现,也是基于Hibernate框架的实现类。

6. Query

package com.core.dao.hibernate;
import java.util.List;
import com.core.dao.IQuery;
public class Query implements IQuery {
	private String queryStr;
	private String sql;
	private Object[] params;
	private int firstResult;
	private int maxResult;
	@SuppressWarnings({ "rawtypes", "unused" })
	private Class[] entityClasses;
	@Override
	public String getQueryString() {
		return queryStr;
	@Override
	public String getSQLString() {
		return sql;
	@Override
	public Object[] getParamValues() {
		return params;
	@Override
	public int getFirstResult() {
		return firstResult;
	@Override
	public int getMaxResults() {
		return maxResult;
	@SuppressWarnings("rawtypes")
	@Override
	public void setEntityClass(Class[] entityClasses) {
		this.entityClasses = entityClasses;
	@Override
	public void setQueryString(String queryStr) {
		this.queryStr = queryStr;
	@Override
	public void setSQLString(String sql) {
		this.sql = sql;
	@Override
	public void setParamValues(Object[] values) {
		this.params = values;
	@Override
	public void setFirstResult(int value) {
		this.firstResult = value;
	@Override
	public void setMaxResults(int value) {
		this.maxResult = value;
	@SuppressWarnings("rawtypes")
	@Override
	public List execute() {
		return null;
}

该类是对IQuery的实现,也是基于Hibernate框架的实现类。

6. applicationContext.xml(部分,其他的自己配)

	<bean id="baseDao" class="com.core.dao.hibernate.BaseDao"></bean>