在spring+hibernate的web项目中,处理数据层通常会使用Spring框架提供的HibernateTemplate类提供的方法。通常的用法是每一个实体类对应的去写DAO层的接口和实现类。每个实现类中都写hibernateTemp.save(entity)、hibernateTemp.update(entity)、hibernateTemp.get(id)...这样写固然没错,但存在着大量的重复代码。所以懒惰的程序员烦了,他们要写一个通用的实现类来解决这个问题,让DAO层解放出来。如果有特殊的需要则在实现类中写个方法去处理,没有特殊的需要那么我们就不用在写DAO层的代码了。
下面是我写的一个通用DAO层接口和实现类,初次写这种通用型的代码可能会有很多不到位的地方,如果您看到了,请在评论中不吝赐教,谢谢!
BaseDao.Java
package org.lxl.mr.common.base.db;
import java.util.List;
/**
* 通用数据层接口
* @author liuXueLiang
* @param <Entity>
* @param <PK>
*/
public interface BaseDao<Entity,PK> {
/**
* 增加
* @param entity
*/
public void save(Entity entity);
/**
* 修改
* @param entity
*/
public void update(Entity entity);
/**
* 删除
* @param entity
*/
public void delete(Entity entity);
/**
* 通过主键删除
* @param pk
* @param pkName
*/
public void deleteByPK(final PK pk,final String pkName);
/**
* 通过主键查询
* @param pk
* @return
*/
public Entity get(PK pk);
/**
* 通过主键查询,延迟加载
* @param pk
* @return
*/
public Entity load(PK pk);
/**
* 查询全部
* @return
*/
public List<Entity> findAll();
}
BaseDaoImpl.java
package org.lxl.mr.common.base.db;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.lxl.mr.common.page.Pagination;
import org.lxl.mr.common.util.ReflectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.Assert;
/**
* 通用数数据层实现
* @author liuXueLiang
* @param <Entity>
* @param <PK>
*/
public class BaseDaoImpl<Entity,PK extends Serializable> extends HibernateDaoSupport implements BaseDao<Entity, PK> {
/**
* 给HibernateDaoSupport中的hibernateTemplate赋值
* @param sessionFactory
*/
@Autowired
public void setMySessionFactory(SessionFactory sessionFactory){
super.setSessionFactory(sessionFactory);
}
/**
* 子类的类对象
*/
private Class<Entity> entityClass;
/**
* 创建对象时给entityClass赋值
*/
protected BaseDaoImpl(){
this.entityClass = ReflectionUtils.getSuperClassGenricType(getClass());
}
/**
* 增加
* @param entity
*/
@Override
public void save(Entity entity) {
super.getHibernateTemplate().save(entity);
}
/**
* 修改
* @param entity
*/
@Override
public void update(Entity entity) {
super.getHibernateTemplate().update(entity);
}
/**
* 通过主键删除 PK为主键的类型
* @param pk 主键值
* @param pkName主键名称(如:id、uuid)
*/
@Override
public void deleteByPK(final PK pk,final String pkName) {
Integer executeCount = super.getHibernateTemplate().execute(new HibernateCallback<Integer>(){
@Override
public Integer doInHibernate(Session session) throws HibernateException, SQLException {
Assert.hasText(pkName);
Assert.notNull(pk);
String hql = "delete from "+entityClass.getName()+" where "+pkName+":=pk";
Query query = session.createQuery(hql);
if(pk instanceof java.lang.Integer){
query.setInteger("pk", (Integer) pk);
}
else if(pk instanceof java.lang.Long){
query.setLong("pk", (Long) pk);
}
else if(pk instanceof java.lang.String){
query.setString("pk", (String) pk);
}
else{
throw new RuntimeException("Does not support the type of the primary key! The primary key only support the type Integer,Long,String types. ");
}
return query.executeUpdate();
}
});
if(executeCount!=1)
throw new RuntimeException("Through the primary key to delete data failed");
}
/**
* 删除
* @param entity
*/
@Override
public void delete(Entity entity) {
super.getHibernateTemplate().delete(entity);
}
/**
* 通过主键查询 PK为主键类型
* @param pk 主键值
*/
@Override
public Entity get(PK pk) {
return super.getHibernateTemplate().get(entityClass, pk);
}
/**
* 通过主键查询,延迟加载 PK为主键类型
* @param pk 主键值
*/
@Override
public Entity load(PK pk) {
return super.getHibernateTemplate().load(this.entityClass, pk);
}
/**
* 查询全部
* @return List<Entity>
*/
@Override
public List<Entity> findAll() {
return this.findListByMap(null);
}
/**
* 根据条件查询唯一对象
* @param map
* @return Entity
*/
public Entity findUnique(final Map<String,Object> map){
return getHibernateTemplate().execute(new HibernateCallback<Entity>(){
@SuppressWarnings("unchecked")
@Override
public Entity doInHibernate(Session session) throws HibernateException, SQLException {
Criteria criteria = session.createCriteria(entityClass);
if(map!=null){
criteria.add(Restrictions.allEq(map));
}
return (Entity) criteria.uniqueResult();
}
});
}
/**
* 根据条件查询
* @param map
* @return List<Entity>
*/
@SuppressWarnings("unchecked")
public List<Entity> findListByMap(final Map<String,Object> map){
return (List<Entity>) getHibernateTemplate().execute(new HibernateCallback<Entity>(){
@Override
public Entity doInHibernate(Session session) throws HibernateException, SQLException {
Criteria criteria = session.createCriteria(entityClass);
if(map!=null){
criteria.add(Restrictions.allEq(map));
}
return (Entity) criteria.list();
}
});
}
@SuppressWarnings("unchecked")
public List<Entity> findListByDetachedCriteria(final DetachedCriteria detachedCriteria){
return (List<Entity>) getHibernateTemplate().execute(new HibernateCallback<List<Entity>>(){
@Override
public List<Entity> doInHibernate(Session session) throws HibernateException, SQLException {
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
return (List<Entity>) criteria.list();
}
});
}
/**
* 使用HQL语句查询唯一对象
* @param hql
* @param paramMap
* @return Entity
*/
@SuppressWarnings("unchecked")
public Entity findByHqlUnique(final String hql,final Map<String,Object> paramMap){
Assert.hasText(hql);
return (Entity) createHqlQuery(hql, paramMap).uniqueResult();
}
/**
* 使用HQL语句查询
* @param hql
* @param paramMap
* @return List<Entity>
*/
@SuppressWarnings("unchecked")
public List<Entity> findByHQL(final String hql,final Map<String,Object> paramMap){
Assert.hasText(hql);
return createHqlQuery(hql, paramMap).list();
}
/**
* 使用SQL语句查询唯一对象
* @param sql
* @param paramMap
* @return
*/
public Object findBySQLUnique(final String sql,final Map<String,Object> paramMap){
Assert.hasLength(sql);
return createSqlQuery(sql, paramMap).uniqueResult();
}
/**
* 使用SQL语句查询唯一对象
* @param sql
* @param paramMap
* @return
*/
@SuppressWarnings("unchecked")
public <T> List<T> findBySQL(final String sql,final Map<String,Object> paramMap){
Assert.hasText(sql);
return (List<T>) createSqlQuery(sql, paramMap).list();
}
/**
* 批处理,使用HQL语句
* @param hql
* @param values
* @return
*/
public int execHQLBatchByMap(final String hql,final Map<String,Object> values){
Assert.hasText(hql);
return getHibernateTemplate().execute(new HibernateCallback<Integer>(){
@Override
public Integer doInHibernate(Session session) throws HibernateException, SQLException {
Query query = session.createQuery(hql);
query.setProperties(values);
return query.executeUpdate();
}
});
}
/**
* 批处理,使用SQL语句
* @param sql
* @param values
* @return
*/
public int execSQLBatchByMap(final String sql,final Map<String,Object> values){
Assert.hasText(sql);
return getHibernateTemplate().execute(new HibernateCallback<Integer>(){
@Override
public Integer doInHibernate(Session session) throws HibernateException, SQLException {
Query query = session.createSQLQuery(sql);
query.setProperties(values);
return query.executeUpdate();
}
});
}
/**
* HQL分页
* @param hql
* @param pageNo
* @param pageSize
* @param map
* @return
*/
@SuppressWarnings("rawtypes")
public Pagination findPageByHql(final String hql,final int pageNo,final int pageSize,
final Map<String,Object> map){
Query query = createHqlQuery(hql, map);
Pagination page = new Pagination();
page.setPageSize(pageSize);
page.setPageNo(pageNo);
return this.pageResult(page, hql, null, query, map);
}
@SuppressWarnings("rawtypes")
public Pagination findPageBySql(final String sql,int pageNo,int pageSize,
final Map<String,Object> map){
Query query = this.createSqlQuery(sql, map);
Pagination page = new Pagination();
page.setPageSize(pageSize);
page.setPageNo(pageNo);
return this.pageResult(page, null, sql, query, map);
}
@SuppressWarnings("rawtypes")
private Pagination pageResult(final Pagination page,String hql,
String sql,Query query,final Map<String,Object> map){
Pagination pagination = page;
Object obj = null;
if(hql!=null && !"".equals(hql)){
obj = createHqlQuery(hql, map).uniqueResult();
}else if(sql!=null && !"".equals(sql)){
obj = createSqlQuery(sql, map).uniqueResult();
}else{
return null;
}
int totalCount = Integer.parseInt(obj.toString());
pagination.setTotalCount(totalCount);
//查询列表,并保存到pagination对象中
if(pagination.getPageSize()>0){
query.setMaxResults(pagination.getPageSize());
query.setFirstResult(pagination.getFirstResult());
}
pagination.setList(query.list());
return pagination;
}
/**
* 创建Query对象,用来处理HQL查询
* @param hql
* @param paramMap
* @return
*/
protected Query createHqlQuery(final String hql,final Map<String,Object> paramMap){
Assert.hasText(hql);
return getHibernateTemplate().execute(new HibernateCallback<Query>(){
@Override
public Query doInHibernate(Session session) throws HibernateException, SQLException {
if(session==null){
session = getSessionFactory().getCurrentSession();
}
Query query = session.createQuery(hql);
query.setProperties(paramMap);
return query;
}
});
}
/**
* 创建Query对象,用来处理SQL查询
* @param sql
* @param paramMap
* @return
*/
protected Query createSqlQuery(final String sql,final Map<String,Object> paramMap){
Assert.hasText(sql);
return getHibernateTemplate().execute(new HibernateCallback<Query>(){
@Override
public Query doInHibernate(Session session) throws HibernateException, SQLException {
Query query = session.createSQLQuery(sql);
query.setProperties(paramMap);
return query;
}
});
}
}
使用
UserDao.java
package org.lxl.mr.dao;
import org.lxl.mr.common.base.db.BaseDao;
import org.lxl.mr.pojo.User;
public interface UserDao extends BaseDao<User, String>{
}
UserDaoImpl.java
package org.lxl.mr.dao.impl;
import org.lxl.mr.common.base.db.BaseDaoImpl;
import org.lxl.mr.dao.UserDao;
import org.lxl.mr.pojo.User;
import org.springframework.stereotype.Component;
@Component
public class UserDaoImpl extends BaseDaoImpl<User, String> implements UserDao {
}