[置顶] 数据持久层(DAO)常用功能–通用API的实现
在Web开发中,一般都分3层。
Controller/Action 控制层,
Service/Business 服务层/业务逻辑层,
Dao 数据访问层/数据持久层。
在学习和工作的实践过程中,我发现很多功能是比较通用的,我们可以把他们抽象成API接口。
下文通过一段较长的代码,Hibernate实现,来展示如何设计一些通用的API。
说明:代码只是起到一个示范(Demo)的作用,实际上完全可以做得更强大。
我最近已经在现在的基础上大大改进了,现在把比较基础的实现分享给大家。
package cn.fansunion.demo.db.dao;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.annotation.Resource;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import cn.fansunion.common.util.EmptyUtils;
/**
* Dao的父类。采用泛型,实现了 一些通用的功能,大大减少了子类代码的重复。
* 目前只能适用于1个表或实体。
*
* @author leiwen@fansunion.cn
*/
public abstract class BaseDao<T> {
private Class<T> modelClazz;
@Resource
private SessionFactory sessionFactory;
// //////////////////////////////////////////////////////////////
public BaseDao() {
this.modelClazz = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
// //////////////////////////////////////////////////////
// //////////////////////泛型方法-CRUD/////////////////////////
// /////////////////////////////////////////////////////
/**
* 根据主键查询
*
* @param id
* 主键
* @return 实体对象
*/
public T get(Integer id) {
T entity = (T) getCurrentSession().get(modelClazz, id);
return entity;
}
/**
* 增加
*
* @param entity
* 实体对象
*/
public void add(T entity) {
getCurrentSession().save(entity);
}
/**
* 物理删除
*
* @param entity
* 实体对象
*/
public void delete(T entity) {
getCurrentSession().delete(entity);
}
/**
* 更新
*
* @param entity
* 持久态的实体对象
*/
public void update(T entity) {
getCurrentSession().update(entity);
}
/**
* 逻辑删除
*
* @param id
* 主键
*/
public void remove(Integer id) {
Session session = getCurrentSession();
String sql = "update " + modelClazz
+ " set isDeleted = 1 where id = :id";
Query query = session.createQuery(sql);
query.setParameter("id", id);
query.executeUpdate();
}
// ///////////////////////////////////////////////
// ////////////获取记录总数/////////////////////////
// ///////////////////////////////////////////////
/**
* 获得1个整数
*
* @param hql
* hql语句
* @return 1个整数
*/
protected Integer getCount(String hql) {
Integer count = 0;
Query query = createQuery(hql);
count = getCount(query);
return count;
}
protected Integer getCount(String hql, String key, Object value) {
Integer count = 0;
Query query = createQuery(hql, key, value);
count = getCount(query);
return count;
}
// 带参数的hql语句
protected Integer getCount(String hql, Map<String, Object> params) {
Integer count = 0;
Query query = createQuery(hql, params);
count = getCount(query);
return count;
}
private Integer getCount(Query query) {
Integer count = 0;
Object uniqueResult = query.uniqueResult();
if (uniqueResult != null) {
count = Integer.parseInt(uniqueResult.toString());
}
return count;
}
// ///////////////////////////////////////////////
// ////////////获取一个对象/////////////////////////
// ///////////////////////////////////////////////
protected List findByProperty(String name, Object value) {
String hql = "from " + modelClazz.getSimpleName() + " where " + name
+ "=" + ":" + name;
return executeQueryList(hql, name, value);
}
protected T executeQueryUnique(String hql) {
T result = null;
List<T> list = executeQueryList(hql);
if (list != null && list.size() >= 1) {
result = list.get(0);
}
return result;
}
protected T executeQueryUnique(String hql, String key, Object value) {
Map<String, Object> params = new HashMap<String, Object>();
params.put(key, value);
return executeQueryUnique(hql, params);
}
// 根据属性获得对象
protected T executeQueryUnique(String hql, String key1, Object value1,
String key2, Object value2) {
Map<String, Object> params = new HashMap<String, Object>();
params.put(key1, value1);
params.put(key2, value2);
return executeQueryUnique(hql, params);
}
protected T executeQueryUnique(String hql, Map<String, Object> params) {
T result = null;
List<T> list = executeQueryList(hql, params);
if (EmptyUtils.isNotEmpty(list)) {
result = list.get(0);
}
return result;
}
// ///////////////////////////////////////////////
// //////////////获取一个列表(不使用泛型 List<T>)/////////////////
// ///////////////////////////////////////////////
// 执行不带参数的hql查询,返回一个结果集List
protected List executeQueryList(String hql) {
return executeQueryList(hql, null);
}
protected List executeQueryList(String hql, String key, Object value) {
Map<String, Object> params = new HashMap<String, Object>();
params.put(key, value);
return executeQueryList(hql, params);
}
protected List executeQueryList(String hql, String key1, Object value1,
String key2, Object value2) {
Map<String, Object> params = new HashMap<String, Object>();
params.put(key1, value1);
params.put(key2, value2);
return executeQueryList(hql, params);
}
protected List executeQueryList(String hql, Map<String, Object> params) {
return executeQueryList(hql, params, -1, -1);
}
protected List executeQueryList(String hql, Integer firstResult,
Integer maxResults) {
return executeQueryList(hql, null, firstResult, maxResults);
}
protected List executeQueryList(String hql, String key, Object value,
Integer firstResult, Integer maxResults) {
Map<String, Object> params = new HashMap<String, Object>();
params.put(key, value);
return executeQueryList(hql, params, firstResult, maxResults);
}
// 执行带参数并且含有分页的hql查询
protected List executeQueryList(String hql, Map<String, Object> params,
Integer firstResult, Integer maxResults) {
Query query = createQuery(hql, params);
if (firstResult > 0) {
query.setFirstResult(firstResult);
}
if (maxResults > 0) {
query.setMaxResults(maxResults);
}
return query.list();
}
// ///////////////////////////////////////////////
// ////////////更新操作/////////////////////////
// ///////////////////////////////////////////////
protected int executeUpdate(String hql) {
return executeUpdate(hql, null);
}
protected int executeUpdate(String hql, String key, Object value) {
Map<String, Object> params = new HashMap<String, Object>();
params.put(key, value);
return executeUpdate(hql, params);
}
protected int executeUpdate(String hql, String key1, Object value1,
String key2, Object value2) {
Map<String, Object> params = new HashMap<String, Object>();
params.put(key1, value1);
params.put(key2, value2);
return executeUpdate(hql, params);
}
// 执行带参数的hql更新语句
protected int executeUpdate(String hql, Map<String, Object> params) {
Query query = createQuery(hql, params);
return query.executeUpdate();
}
// ///////////////////////////////////////////////
// ////////////创建Query对象/////////////////////////
// ///////////////////////////////////////////////
private Query createQuery(String hql, Map<String, Object> params) {
Query query = getCurrentSession().createQuery(hql);
if (params != null) {
Set<Entry<String, Object>> entrySet = params.entrySet();
for (Map.Entry<String, Object> entry : entrySet) {
Object value = entry.getValue();
String key = entry.getKey();
if (value instanceof Collection) {
query.setParameterList(key, (Collection) value);
} else if (value instanceof Object[]) {
query.setParameterList(key, (Object[]) value);
} else {
query.setParameter(key, value);
}
}
}
return query;
}
private Query createQuery(String hql, String key, Object value) {
Query query = getCurrentSession().createQuery(hql);
if (key != null) {
query.setParameter(key, value);
}
return query;
}
private Query createQuery(String hql) {
return getCurrentSession().createQuery(hql);
}
/**
* 获取主数源
*/
protected Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
在工作和学习的实践中,我发现Web开发有很大程度上的通用性。
我希望,也在努力地总结这些规律,争取早点弄出一套可以大大提高生产力的方法和代码框架。
技术不能改变程序员的命运,而生产力可以。
提高生产力,是我目前迫切的追求。
过去,现在和未来,我都将为之而努力。
我的博客网站:http://FansUnion.cn
原文参见:http://fansunion.cn/articles/2264