hibernate 通用泛型DAO

时间:2022-09-17 12:57:55
  1. package org.lzpeng.dao;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.List;  
  5. import org.hibernate.Criteria;  
  6. import org.hibernate.Query;  
  7. import org.hibernate.criterion.Criterion;  
  8. import org.springside.modules.orm.hibernate.Page;  
  9.   
  10.   
  11. /**  
  12.  *   
  13.  * @version 2009-1-10  
  14.  * @author lzpeng  
  15.  *   
  16.  */  
  17. public interface IGenericDAO<T, PK extends Serializable> {  
  18.   
  19.     public void save(T entity);  
  20.   
  21.     public void delete(T entity);  
  22.   
  23.     public void delete(PK id);  
  24.   
  25.     public List<T> findAll();  
  26.   
  27.     public Page<T> findAll(Page<T> page);  
  28.   
  29.     /**  
  30.      * 按id获取对象.  
  31.      */  
  32.     public T get(final PK id);  
  33.   
  34.     /**  
  35.      * 按HQL查询对象列表.  
  36.      *   
  37.      * @param hql  
  38.      *            hql语句  
  39.      * @param values  
  40.      *            数量可变的参数  
  41.      */  
  42.     public List find(String hql, Object... values);  
  43.   
  44.     /**  
  45.      * 按HQL分页查询. 暂不支持自动获取总结果数,需用户另行执行查询.  
  46.      *   
  47.      * @param page  
  48.      *            分页参数.包括pageSize 和firstResult.  
  49.      * @param hql  
  50.      *            hql语句.  
  51.      * @param values  
  52.      *            数量可变的参数.  
  53.      *   
  54.      * @return 分页查询结果,附带结果列表及所有查询时的参数.  
  55.      */  
  56.     public Page<T> find(Page<T> page, String hql, Object... values);  
  57.   
  58.     /**  
  59.      * 按HQL查询唯一对象.  
  60.      */  
  61.     public Object findUnique(String hql, Object... values);  
  62.   
  63.     /**  
  64.      * 按HQL查询Intger类形结果.  
  65.      */  
  66.     public Integer findInt(String hql, Object... values);  
  67.   
  68.     /**  
  69.      * 按HQL查询Long类型结果.  
  70.      */  
  71.     public Long findLong(String hql, Object... values);  
  72.   
  73.     /**  
  74.      * 按Criterion查询对象列表.  
  75.      *   
  76.      * @param criterion  
  77.      *            数量可变的Criterion.  
  78.      */  
  79.     public List<T> findByCriteria(Criterion... criterion);  
  80.   
  81.     /**  
  82.      * 按Criterion分页查询.  
  83.      *   
  84.      * @param page  
  85.      *            分页参数.包括pageSize、firstResult、orderBy、asc、autoCount.  
  86.      *            其中firstResult可直接指定,也可以指定pageNo. autoCount指定是否动态获取总结果数.  
  87.      *   
  88.      * @param criterion  
  89.      *            数量可变的Criterion.  
  90.      * @return 分页查询结果.附带结果列表及所有查询时的参数.  
  91.      */  
  92.     public Page<T> findByCriteria(Page page, Criterion... criterion);  
  93.   
  94.     /**  
  95.      * 按属性查找对象列表.  
  96.      */  
  97.     public List<T> findByProperty(String propertyName, Object value);  
  98.   
  99.     /**  
  100.      * 按属性查找唯一对象.  
  101.      */  
  102.     public T findUniqueByProperty(String propertyName, Object value);  
  103.   
  104.     /**  
  105.      * 根据查询函数与参数列表创建Query对象,后续可进行更多处理,辅助函数.  
  106.      */  
  107.     public Query createQuery(String queryString, Object... values);  
  108.   
  109.     /**  
  110.      * 根据Criterion条件创建Criteria,后续可进行更多处理,辅助函数.  
  111.      */  
  112.     public Criteria createCriteria(Criterion... criterions);  
  113.   
  114.     /**  
  115.      * 判断对象的属性值在数据库内是否唯一.  
  116.      *   
  117.      */  
  118.     public boolean isPropertyUnique(String propertyName, Object newValue,  
  119.             Object orgValue);  
  120.   
  121.     /**  
  122.      * 通过count查询获得本次查询所能获得的对象总数.  
  123.      *   
  124.      * @return page对象中的totalCount属性将赋值.  
  125.      */  
  126.     public int countQueryResult(Page<T> page, Criteria c);  
  127. }  

 

实现类代码  hibernate 通用泛型DAO
  1. package org.lzpeng.dao.impl;  
  2.   
  3. import java.io.Serializable;  
  4. import java.lang.reflect.ParameterizedType;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7.   
  8. import org.hibernate.Criteria;  
  9. import org.hibernate.Query;  
  10. import org.hibernate.Session;  
  11. import org.hibernate.SessionFactory;  
  12. import org.hibernate.criterion.CriteriaSpecification;  
  13. import org.hibernate.criterion.Criterion;  
  14. import org.hibernate.criterion.Order;  
  15. import org.hibernate.criterion.Projection;  
  16. import org.hibernate.criterion.Projections;  
  17. import org.hibernate.criterion.Restrictions;  
  18. import org.hibernate.impl.CriteriaImpl;  
  19. import org.hibernate.transform.ResultTransformer;  
  20. import org.slf4j.Logger;  
  21. import org.slf4j.LoggerFactory;  
  22. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;  
  23. import org.springframework.util.Assert;  
  24. import org.lzpeng.dao.IGenericDAO;  
  25. import org.springside.modules.utils.BeanUtils;  
  26. import org.springside.modules.orm.hibernate.Page;  
  27. import org.springside.modules.orm.hibernate.QueryParameter;  
  28.   
  29. /**  
  30.  * Hibernate的范型基类.  
  31.  * <p>  
  32.  * 可以在service类中直接创建使用.也可以继承出DAO子类  
  33.  * </p>  
  34.  * 修改自Springside SimpleHibernateTemplate  
  35.  *   
  36.  * @param <T>  
  37.  *            DAO操作的对象类型  
  38.  * @param <PK>  
  39.  *            主键类型  
  40.  *   
  41.  *   
  42.  */  
  43. @SuppressWarnings("unchecked")  
  44. public class GenericDAOImpl<T, PK extends Serializable> extends  
  45.         HibernateDaoSupport implements IGenericDAO<T, PK> {  
  46.   
  47.     protected Logger logger = LoggerFactory.getLogger(getClass());  
  48.   
  49.     protected SessionFactory sessionFactory;  
  50.   
  51.     protected Session session;  
  52.   
  53.     protected Class<?> entityClass;  
  54.           
  55.     public GenericDAOImpl() {  
  56.         this.entityClass = (Class<?>) ((ParameterizedType) getClass()  
  57.                 .getGenericSuperclass()).getActualTypeArguments()[0];  
  58.     }  
  59.   
  60.     public GenericDAOImpl(SessionFactory sessionFactory, Class<T> entityClass) {        
  61.         super.setSessionFactory(sessionFactory);  
  62.         this.entityClass = entityClass;  
  63.     }  
  64.   
  65.     public void save(T entity) {  
  66.         Assert.notNull(entity);  
  67.         super.getHibernateTemplate().saveOrUpdate(entity);  
  68.         logger.info("save entity: {}", entity);  
  69.     }  
  70.   
  71.     public void delete(T entity) {  
  72.         Assert.notNull(entity);  
  73.         super.getHibernateTemplate().delete(entity);  
  74.         logger.info("delete entity: {}", entity);  
  75.     }  
  76.   
  77.     public void delete(PK id) {  
  78.         Assert.notNull(id);  
  79.         delete(get(id));  
  80.     }  
  81.   
  82.     public List<T> findAll() {  
  83.         return findByCriteria();  
  84.     }  
  85.   
  86.     public Page<T> findAll(Page<T> page) {  
  87.         return findByCriteria(page);  
  88.     }  
  89.   
  90.     public T get(final PK id) {  
  91.         if(super.getHibernateTemplate() == null){  
  92.             System.out.println("asdfasdf");  
  93.         }  
  94.         return (T) super.getHibernateTemplate().get(entityClass, id);  
  95.     }  
  96.   
  97.     public List find(String hql, Object... values) {  
  98.         return createQuery(hql, values).list();  
  99.     }  
  100.   
  101.     public Page<T> find(Page<T> page, String hql, Object... values) {  
  102.         Assert.notNull(page);  
  103.   
  104.         if (page.isAutoCount()) {  
  105.             logger.warn("HQL查询暂不支持自动获取总结果数,hql为{}", hql);  
  106.         }  
  107.         Query q = createQuery(hql, values);  
  108.         if (page.isFirstSetted()) {  
  109.             q.setFirstResult(page.getFirst());  
  110.         }  
  111.         if (page.isPageSizeSetted()) {  
  112.             q.setMaxResults(page.getPageSize());  
  113.         }  
  114.         page.setResult(q.list());  
  115.         return page;  
  116.     }  
  117.   
  118.     /**  
  119.      * 按HQL查询唯一对象.  
  120.      */  
  121.     public Object findUnique(String hql, Object... values) {  
  122.         return createQuery(hql, values).uniqueResult();  
  123.     }  
  124.   
  125.     public Integer findInt(String hql, Object... values) {  
  126.         return (Integer) findUnique(hql, values);  
  127.     }  
  128.   
  129.     public Long findLong(String hql, Object... values) {  
  130.         return (Long) findUnique(hql, values);  
  131.     }  
  132.   
  133.     public List<T> findByCriteria(Criterion... criterion) {  
  134.         return createCriteria(criterion).list();  
  135.     }  
  136.   
  137.     public Page<T> findByCriteria(Page page, Criterion... criterion) {  
  138.         Assert.notNull(page);  
  139.   
  140.         Criteria c = createCriteria(criterion);  
  141.   
  142.         if (page.isAutoCount()) {  
  143.             page.setTotalCount(countQueryResult(page, c));  
  144.         }  
  145.         if (page.isFirstSetted()) {  
  146.             c.setFirstResult(page.getFirst());  
  147.         }  
  148.         if (page.isPageSizeSetted()) {  
  149.             c.setMaxResults(page.getPageSize());  
  150.         }  
  151.   
  152.         if (page.isOrderBySetted()) {  
  153.             if (page.getOrder().endsWith(QueryParameter.ASC)) {  
  154.                 c.addOrder(Order.asc(page.getOrderBy()));  
  155.             } else {  
  156.                 c.addOrder(Order.desc(page.getOrderBy()));  
  157.             }  
  158.         }  
  159.         page.setResult(c.list());  
  160.         return page;  
  161.     }  
  162.   
  163.     /**  
  164.      * 按属性查找对象列表.  
  165.      */  
  166.     public List<T> findByProperty(String propertyName, Object value) {  
  167.         Assert.hasText(propertyName);  
  168.         return createCriteria(Restrictions.eq(propertyName, value)).list();  
  169.     }  
  170.   
  171.     public T findUniqueByProperty(String propertyName, Object value) {  
  172.         Assert.hasText(propertyName);  
  173.         return (T) createCriteria(Restrictions.eq(propertyName, value))  
  174.                 .uniqueResult();  
  175.     }  
  176.   
  177.     public Query createQuery(String queryString, Object... values) {  
  178.          Assert.hasText(queryString);  
  179.          super.getSession().createQuery(queryString);  
  180.         Query queryObject = super.getSession().createQuery(queryString);  
  181.         if (values != null) {  
  182.             for (int i = 0; i < values.length; i++) {  
  183.                 queryObject.setParameter(i, values[i]);  
  184.             }  
  185.         }  
  186.         return queryObject;  
  187.     }  
  188.   
  189.       
  190.     public Criteria createCriteria(Criterion... criterions) {  
  191.         Criteria criteria = super.getSession().createCriteria(entityClass);  
  192.         for (Criterion c : criterions) {  
  193.             criteria.add(c);  
  194.         }  
  195.         return criteria;  
  196.     }  
  197.   
  198.       
  199.     public boolean isPropertyUnique(String propertyName, Object newValue,  
  200.             Object orgValue) {  
  201.         if (newValue == null || newValue.equals(orgValue))  
  202.             return true;  
  203.   
  204.         Object object = findUniqueByProperty(propertyName, newValue);  
  205.         return (object == null);  
  206.     }  
  207.   
  208.     public int countQueryResult(Page<T> page, Criteria c) {  
  209.         CriteriaImpl impl = (CriteriaImpl) c;  
  210.   
  211.         // 先把Projection、ResultTransformer、OrderBy取出来,清空三者后再执行Count操作  
  212.         Projection projection = impl.getProjection();  
  213.         ResultTransformer transformer = impl.getResultTransformer();  
  214.   
  215.         List<CriteriaImpl.OrderEntry> orderEntries = null;  
  216.         try {  
  217.             orderEntries = (List) BeanUtils.getFieldValue(impl, "orderEntries");  
  218.             BeanUtils.setFieldValue(impl, "orderEntries", new ArrayList());  
  219.         } catch (Exception e) {  
  220.             logger.error("不可能抛出的异常:{}", e.getMessage());  
  221.         }  
  222.   
  223.         // 执行Count查询  
  224.         int totalCount = (Integer) c.setProjection(Projections.rowCount())  
  225.                 .uniqueResult();  
  226.         if (totalCount < 1)  
  227.             return -1;  
  228.   
  229.         // 将之前的Projection和OrderBy条件重新设回去  
  230.         c.setProjection(projection);  
  231.   
  232.         if (projection == null) {  
  233.             c.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);  
  234.         }  
  235.         if (transformer != null) {  
  236.             c.setResultTransformer(transformer);  
  237.         }  
  238.   
  239.         try {  
  240.             BeanUtils.setFieldValue(impl, "orderEntries", orderEntries);  
  241.         } catch (Exception e) {  
  242.             logger.error("不可能抛出的异常:{}", e.getMessage());  
  243.         }  
  244.   
  245.         return totalCount;  
  246.     }  
  247.   
  248. }  

 

使用方法代码  hibernate 通用泛型DAO
  1. 1.service中直接使用  
  2. GenericDAOImpl<User, Integer> userDAO = new GenericDAOImpl<User, Integer>(sessionFactory, User.class);  
  3.   
  4. 2.继承出子DAO  
  5. interface IUserDAO extends IGenericDAO<User, Integer>  
  6.   
  7. class UserDAOImpl extends GenericDAOImpl<User, Integer> implements IUserDAO