泛型Hibernate DAO实现基本操作

来源:互联网 发布:剑雨江湖10进阶数据 编辑:程序博客网 时间:2024/06/05 18:56

一个泛型hibernate DAO,用了spring的HibernateDaoSupport。提供基本的CRUD操作,支持分页查询,可使用HQL、Criteria和DetachedCriteria.

[sql] view plain copy
  1. package sgf4web.dao;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.*;  
  5. import java.util.regex.Matcher;  
  6. import java.util.regex.Pattern;  
  7.   
  8. import org.hibernate.*;  
  9. import org.hibernate.criterion.*;  
  10. import org.springframework.orm.hibernate3.HibernateCallback;  
  11. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;  
  12.   
  13. import sgf4web.dao.support.PaginationSupport;  
  14. import sgf4web.util.GenericsUtils;  
  15.   
  16. /**  
  17.  * 泛型Hibernate DAO类  
  18.  *   
  19.  * @author DigitalSonic  
  20.  */  
  21. @SuppressWarnings("unchecked")  
  22. public class HibernateGenericDao<T, ID extends Serializable> extends HibernateDaoSupport {  
  23.     private Class<T> pojoClass;  
  24.       
  25.     /**  
  26.      * 初始化DAO,获取POJO类型  
  27.      */  
  28.     public HibernateGenericDao() {  
  29. //        this.pojoClass = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];  
  30.         this.pojoClass = GenericsUtils.getSuperClassGenricType(getClass());  
  31.     }  
  32.       
  33.     /**  
  34.      * 获得该DAO对应的POJO类型  
  35.      */  
  36.     public Class<T> getPojoClass() {  
  37.         return this.pojoClass;  
  38.     }  
  39.       
  40.     /**  
  41.      * 获得该DAO对应的POJO类型名  
  42.      */  
  43.     public String getPojoClassName() {  
  44.         return getPojoClass().getName();  
  45.     }  
  46.   
  47.     //加载对象  
  48.       
  49.     /**  
  50.      * 加载所有的对象  
  51.      */  
  52.     public List<T> loadAll() {  
  53.         return (List<T>)getHibernateTemplate().loadAll(getPojoClass());  
  54.     }  
  55.       
  56.     /**  
  57.      * 根据hql查询  
  58.      *  
  59.      * @param values 可变参数  
  60.      */  
  61.     public List find(String hql, Object... values) {  
  62.         return getHibernateTemplate().find(hql, values);  
  63.     }  
  64.   
  65.     /**  
  66.      * 根据条件加载对象  
  67.      *   
  68.      * @param criteria Criteria实例  
  69.      */  
  70.     public List<T> findByCriteria(final Criteria criteria) {  
  71.         List list = criteria.list();   
  72.         return transformResults(list);  
  73.     }  
  74.       
  75.     /**  
  76.      * 根据条件加载对象  
  77.      * @param detachedCriteria DetachedCriteria实例  
  78.      */  
  79.     public List<T> findByCriteria(final DetachedCriteria detachedCriteria) {  
  80.         return (List<T>) getHibernateTemplate().execute(new HibernateCallback() {  
  81.                public Object doInHibernate(Session session) throws HibernateException {  
  82.                    Criteria criteria = detachedCriteria.getExecutableCriteria(session);  
  83.                    List list = criteria.list();   
  84.                    return transformResults(list);   
  85.                }  
  86.            }, true);  
  87.     }  
  88.       
  89.     /**  
  90.      * 根据给定的实例查找对象  
  91.      */  
  92.     public List<T> findByExample(T instance) {  
  93.         List<T> results = (List<T>)getHibernateTemplate().findByExample(instance);  
  94.         return results;  
  95.     }      
  96.       
  97.     /**  
  98.      * 根据ID查找对象  
  99.      */  
  100.     public T findById(ID id) {  
  101.         return (T) getHibernateTemplate().get(getPojoClassName(), id);  
  102.     }  
  103.       
  104.     /**  
  105.      * 根据某个具体属性进行查找  
  106.      */  
  107.     public List<T> findByProperty(String propertyName, Object value) {  
  108.        String queryString = "from " + getPojoClassName() + " as model where model."   
  109.                                + propertyName + "= ?";  
  110.        return (List<T>)getHibernateTemplate().find(queryString, value);  
  111.     }  
  112.       
  113.     //新建、修改、删除  
  114.       
  115.     /**  
  116.      * 新建对象实例化  
  117.      */  
  118.     public ID save(T transientInstance) {  
  119.         return (ID)getHibernateTemplate().save(transientInstance);  
  120.     }  
  121.       
  122.     /**  
  123.      * 更新已存在的对象  
  124.      */  
  125.     public void update(T transientInstance) {  
  126.         getHibernateTemplate().update(transientInstance);  
  127.     }  
  128.       
  129.     /**  
  130.      * 删除指定ID的对象  
  131.      */  
  132.     public void delete(ID id) {  
  133.            T instance = findById(id);  
  134.            if (instance != null)  
  135.                getHibernateTemplate().delete(instance);  
  136.     }  
  137.       
  138.     /**  
  139.      * 删除指定对象  
  140.      */  
  141.     public void delete(T persistentInstance) {  
  142.         getHibernateTemplate().delete(persistentInstance);  
  143.     }      
  144.       
  145.     //分页  
  146.     /**  
  147.      * 根据Criteria加载分页,指定页大小和起始位置  
  148.      */  
  149.     public PaginationSupport findPageByCriteria(final Criteria criteria, final int pageSize, final int startIndex) {     
  150.         int totalCount = getCountByCriteria(criteria);     
  151.         criteria.setProjection(null);  
  152.         List items = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();  
  153.         items = transformResults(items);  
  154.         PaginationSupport ps = new PaginationSupport(items, totalCount, pageSize, startIndex);  
  155.         return ps;  
  156.     }  
  157.       
  158.     /**  
  159.      * 根据Criteria加载分页,默认页大小,从第0条开始  
  160.      */  
  161.     public PaginationSupport findPageByCriteria(final Criteria criteria) {     
  162.         return findPageByCriteria(criteria, PaginationSupport.PAGESIZE, 0);     
  163.     }     
  164.    
  165.     /**  
  166.      * 根据Criteria加载分页,默认页大小,从第startIndex条开始  
  167.      */  
  168.     public PaginationSupport findPageByCriteria(final Criteria criteria, final int startIndex) {     
  169.         return findPageByCriteria(criteria, PaginationSupport.PAGESIZE, startIndex);     
  170.     }  
  171.       
  172.     /**  
  173.      * 根据Criteria统计总数  
  174.      */  
  175.     public int getCountByCriteria(final Criteria criteria) {     
  176.         Integer count = (Integer) criteria.setProjection(Projections.rowCount()).uniqueResult();      
  177.         return count.intValue();     
  178.     }  
  179.       
  180.     /**  
  181.      * 根据DetachedCriteria加载分页,指定页大小和起始位置  
  182.      */  
  183.     public PaginationSupport findPageByCriteria(final DetachedCriteria detachedCriteria, final int pageSize, final int startIndex) {     
  184.         return (PaginationSupport) getHibernateTemplate().execute(new HibernateCallback() {     
  185.             public Object doInHibernate(Session session) throws HibernateException {     
  186.                 Criteria criteria = detachedCriteria.getExecutableCriteria(session);  
  187.                 int totalCount = ((Integer) criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();     
  188.                 criteria.setProjection(null);  
  189.                 List items = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();  
  190.                 items = transformResults(items);  
  191.                 PaginationSupport ps = new PaginationSupport(items, totalCount, pageSize, startIndex);     
  192.                 return ps;     
  193.             }  
  194.         }, true);     
  195.     }  
  196.       
  197.     /**  
  198.      * 根据DetachedCriteria加载分页,默认页大小,从第0条开始  
  199.      */  
  200.     public PaginationSupport findPageByCriteria(final DetachedCriteria detachedCriteria) {     
  201.         return findPageByCriteria(detachedCriteria, PaginationSupport.PAGESIZE, 0);     
  202.     }     
  203.     
  204.     /**  
  205.      * 根据DetachedCriteria加载分页,默认页大小,从第startIndex条开始  
  206.      */  
  207.     public PaginationSupport findPageByCriteria(final DetachedCriteria detachedCriteria, final int startIndex) {     
  208.         return findPageByCriteria(detachedCriteria, PaginationSupport.PAGESIZE, startIndex);     
  209.     }   
  210.       
  211.     /**  
  212.      * 根据DetachedCriteria统计总数  
  213.      */  
  214.     public int getCountByCriteria(final DetachedCriteria detachedCriteria) {     
  215.         Integer count = (Integer) getHibernateTemplate().execute(new HibernateCallback() {     
  216.             public Object doInHibernate(Session session) throws HibernateException {     
  217.                 Criteria criteria = detachedCriteria.getExecutableCriteria(session);     
  218.                 return criteria.setProjection(Projections.rowCount()).uniqueResult();     
  219.             }     
  220.         }, true);     
  221.         return count.intValue();     
  222.     }   
  223.       
  224.     /**  
  225.      * 根据hql加载分页,指定页大小和起始位置  
  226.      */  
  227.     public PaginationSupport findPageByQuery(final String hql, final int pageSize, final int startIndex, Object...values) {  
  228.         int totalCount = getCountByQuery(hql, values);  
  229.           
  230.         if (totalCount < 1)  
  231.             return new PaginationSupport(new ArrayList(0), 0);  
  232.   
  233.         Query query = createQuery(hql, values);  
  234.         List items = query.setFirstResult(startIndex).setMaxResults(pageSize).list();  
  235.         PaginationSupport ps = new PaginationSupport(items, totalCount, pageSize, startIndex);  
  236.         return ps;  
  237.     }  
  238.       
  239.     /**  
  240.      * 根据hql加载分页,默认页大小,从第0条开始  
  241.      */  
  242.     public PaginationSupport findPageByQuery(final String hql, Object...values) {     
  243.         return findPageByQuery(hql, PaginationSupport.PAGESIZE, 0, values);     
  244.     }     
  245.    
  246.     /**  
  247.      * 根据hql加载分页,默认页大小,从第startIndex条开始  
  248.      */  
  249.     public PaginationSupport findPageByQuery(final String hql, final int startIndex, Object...values) {     
  250.         return findPageByQuery(hql, PaginationSupport.PAGESIZE, startIndex, values);    
  251.     }  
  252.       
  253.     /**  
  254.      * 根据hql统计总数  
  255.      */  
  256.     public int getCountByQuery(final String hql, Object...values) {     
  257.         String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));  
  258.         List countlist = getHibernateTemplate().find(countQueryString, values);  
  259.         return (Integer) countlist.get(0);  
  260.     }  
  261.       
  262.     //创建Criteria和Query  
  263.       
  264.     /**  
  265.      * 创建Criteria对象  
  266.      *  
  267.      * @param criterions 可变的Restrictions条件列表  
  268.      */  
  269.     public Criteria createCriteria(Criterion...criterions) {  
  270.         Criteria criteria = getSession().createCriteria(getPojoClass());  
  271.         for (Criterion c : criterions)  
  272.             criteria.add(c);  
  273.         return criteria;  
  274.     }  
  275.   
  276.     /**  
  277.      * 创建Criteria对象,带排序字段与升降序字段  
  278.      */  
  279.     public Criteria createCriteria(String orderBy, boolean isAsc, Criterion...criterions) {  
  280.         Criteria criteria = createCriteria(criterions);  
  281.         if (isAsc)  
  282.             criteria.addOrder(Order.asc(orderBy));  
  283.         else  
  284.             criteria.addOrder(Order.desc(orderBy));  
  285.         return criteria;  
  286.     }  
  287.       
  288.     /**  
  289.      * 方法取自SpringSide.  
  290.      * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.  
  291.      * 留意可以连续设置,如下:  
  292.      * <pre>  
  293.      * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();  
  294.      * </pre>  
  295.      * 调用方式如下:  
  296.      * <pre>  
  297.      *        dao.createQuery(hql)  
  298.      *        dao.createQuery(hql,arg0);  
  299.      *        dao.createQuery(hql,arg0,arg1);  
  300.      *        dao.createQuery(hql,new Object[arg0,arg1,arg2])  
  301.      * </pre>  
  302.      *  
  303.      * @param values 可变参数.  
  304.      */  
  305.     public Query createQuery(String hql, Object... values) {  
  306.         Query query = getSession().createQuery(hql);  
  307.         for (int i = 0; i < values.length; i++) {  
  308.             query.setParameter(i, values[i]);  
  309.         }  
  310.         return query;  
  311.     }  
  312.       
  313.     /**  
  314.      * 方法取自SpringSide.  
  315.      * 去除hql的select子句,未考虑union的情况  
  316.      */  
  317.     private static String removeSelect(String hql) {  
  318.         int beginPos = hql.toLowerCase().indexOf("from");  
  319.         return hql.substring(beginPos);  
  320.     }  
  321.   
  322.     /**  
  323.      * 方法取自SpringSide.  
  324.      * 去除hql的orderby子句  
  325.      */  
  326.     private static String removeOrders(String hql) {  
  327.         Pattern p = Pattern.compile("order/s*by[/w|/W|/s|/S]*", Pattern.CASE_INSENSITIVE);  
  328.         Matcher m = p.matcher(hql);  
  329.         StringBuffer sb = new StringBuffer();  
  330.         while (m.find()) {  
  331.             m.appendReplacement(sb, "");  
  332.         }  
  333.         m.appendTail(sb);  
  334.         return sb.toString();  
  335.     }  
  336.       
  337.     /**  
  338.      * 将联合查询的结果内容从Map或者Object[]转换为实体类型,如果没有转换必要则直接返回  
  339.      */  
  340.     private List transformResults(List items) {  
  341.         if (items.size() > 0) {  
  342.             if (items.get(0) instanceof Map) {  
  343.                 ArrayList list = new ArrayList(items.size());  
  344.                 for (int i = 0; i < items.size(); i++) {  
  345.                     Map map = (Map)items.get(i);  
  346.                     list.add(map.get(CriteriaSpecification.ROOT_ALIAS));  
  347.                 }  
  348.                 return list;  
  349.             } else if (items.get(0) instanceof Object[]) {  
  350.                 ArrayList list = new ArrayList(items.size());  
  351.                 int pos = 0;  
  352.                 for (int i = 0; i < ((Object[])items.get(0)).length; i++) {  
  353.                     if (((Object[])items.get(0))[i].getClass() == getPojoClass()) {  
  354.                         pos = i;  
  355.                         break;  
  356.                     }  
  357.                 }  
  358.                 for (int i = 0; i < items.size(); i++) {  
  359.                     list.add(((Object[])items.get(i))[pos]);  
  360.                 }  
  361.                 return list;  
  362.             } else  
  363.                 return items;  
  364.         } else  
  365.             return items;  
  366.     }  
  367. }  

[sql] view plain copy
  1. package sgf4web.util;  
  2.   
  3. import java.lang.reflect.ParameterizedType;  
  4. import java.lang.reflect.Type;  
  5.   
  6. /**  
  7.  * 泛型参数辅助类  
  8.  *   
  9.  * @author DigitalSonic  
  10.  */  
  11. @SuppressWarnings("unchecked")  
  12. public class GenericsUtils {  
  13.     /**  
  14.      * 通过反射,获得定义Class时声明的父类的第一个范型参数的类型。  
  15.      */  
  16.     public static Class getSuperClassGenricType(Class clazz) {  
  17.         return getSuperClassGenricType(clazz, 0);  
  18.     }  
  19.       
  20.     /**  
  21.      * 通过反射,获得定义Class时声明的父类的范型参数的类型。  
  22.      * 如没有找到符合要求的范型参数,则递归向上直到Object。  
  23.      *  
  24.      * @param clazz 要进行查询的类  
  25.      * @param index 如有多个范型声明该索引从0开始  
  26.      * @return 在index位置的范型参数的类型,如果无法判断则返回<code>Object.class</code>  
  27.      */  
  28.     public static Class getSuperClassGenricType(Class clazz, int index) {  
  29.         boolean flag = true;  
  30.         Type genType = clazz.getGenericSuperclass();  
  31.         Type[] params = null;  
  32.           
  33.         if (!(genType instanceof ParameterizedType))  
  34.             flag = false;  
  35.         else {  
  36.             params = ((ParameterizedType) genType).getActualTypeArguments();  
  37.             if (index >= params.length || index < 0)  
  38.                 flag = false;  
  39.             if (!(params[index] instanceof Class))  
  40.                 flag = false;  
  41.         }  
  42.         if (!flag) {  
  43.             clazz = clazz.getSuperclass();  
  44.             if (clazz == Object.class)  
  45.                 return Object.class;  
  46.             else  
  47.                 return getSuperClassGenricType(clazz, index);  
  48.         }  
  49.           
  50.         return (Class) params[index];  
  51.     }  
  52. }  
[sql] view plain copy
  1. package sgf4web.dao.support;  
  2.   
  3. import java.util.List;  
  4.   
  5. /**  
  6.  * 分页类,参考自JavaEye及SpringSide  
  7.  */  
  8. @SuppressWarnings("unchecked")  
  9. public class PaginationSupport {  
  10.     public final static int PAGESIZE = 10;  
  11.   
  12.     private int pageSize = PAGESIZE;  
  13.   
  14.     private List items;  
  15.   
  16.     private int totalCount;  
  17.   
  18.     private int[] indexes = new int[0];  
  19.   
  20.     private int startIndex = 0;  
  21.   
  22.     public PaginationSupport(List items, int totalCount) {  
  23.         setPageSize(PAGESIZE);  
  24.         setTotalCount(totalCount);  
  25.         setItems(items);  
  26.         setStartIndex(0);  
  27.     }  
  28.   
  29.     public PaginationSupport(List items, int totalCount, int startIndex) {  
  30.         setPageSize(PAGESIZE);  
  31.         setTotalCount(totalCount);  
  32.         setItems(items);  
  33.         setStartIndex(startIndex);  
  34.     }  
  35.   
  36.     public PaginationSupport(List items, int totalCount, int pageSize, int startIndex) {  
  37.         setPageSize(pageSize);  
  38.         setTotalCount(totalCount);  
  39.         setItems(items);  
  40.         setStartIndex(startIndex);  
  41.     }  
  42.   
  43.     /**  
  44.      * 将页码转换为列表的startIndex,页大小为默认大小  
  45.      */  
  46.     public static int convertFromPageToStartIndex(int pageNo) {  
  47.         return (pageNo - 1) * PAGESIZE;  
  48.     }  
  49.       
  50.     /**  
  51.      * 将页码转换为列表的startIndex  
  52.      */  
  53.     public static int convertFromPageToStartIndex(int pageNo, int pageSize) {  
  54.         return (pageNo - 1) * pageSize;  
  55.     }  
  56.   
  57.     public List getItems() {  
  58.         return items;  
  59.     }  
  60.   
  61.     public void setItems(List items) {  
  62.         this.items = items;  
  63.     }  
  64.   
  65.     public int getPageSize() {  
  66.         return pageSize;  
  67.     }  
  68.   
  69.     public void setPageSize(int pageSize) {  
  70.         this.pageSize = pageSize;  
  71.     }  
  72.   
  73.     public int getTotalCount() {  
  74.         return totalCount;  
  75.     }  
  76.   
  77.     /**  
  78.      * 设置数据总数,并计算各页起始位置  
  79.      */  
  80.     public void setTotalCount(int totalCount) {  
  81.         if (totalCount > 0) {  
  82.             this.totalCount = totalCount;  
  83.             int count = totalCount / pageSize;  
  84.             if (totalCount % pageSize > 0)  
  85.                 count++;  
  86.             indexes = new int[count];  
  87.             for (int i = 0; i < count; i++) {  
  88.                 indexes[i] = pageSize * i;  
  89.             }  
  90.         } else {  
  91.             this.totalCount = 0;  
  92.         }  
  93.     }  
  94.   
  95.     public int[] getIndexes() {  
  96.         return indexes;  
  97.     }  
  98.   
  99.     public void setIndexes(int[] indexes) {  
  100.         this.indexes = indexes;  
  101.     }  
  102.   
  103.     public int getStartIndex() {  
  104.         return startIndex;  
  105.     }  
  106.   
  107.     /**  
  108.      * 设置当前起始位置  
  109.      */  
  110.     public void setStartIndex(int startIndex) {  
  111.         if (totalCount <= 0)  
  112.             this.startIndex = 0;  
  113.         else if (startIndex >= totalCount)  
  114.             this.startIndex = indexes[indexes.length - 1];  
  115.         else if (startIndex < 0)  
  116.             this.startIndex = 0;  
  117.         else {  
  118.             this.startIndex = indexes[startIndex / pageSize];  
  119.         }  
  120.     }  
  121.   
  122.     /**  
  123.      * 获得下页起始位置  
  124.      */  
  125.     public int getNextIndex() {  
  126.         int nextIndex = getStartIndex() + pageSize;  
  127.         if (nextIndex >= totalCount)  
  128.             return getStartIndex();  
  129.         else  
  130.             return nextIndex;  
  131.     }  
  132.   
  133.     /**  
  134.      * 获得上页起始位置  
  135.      */  
  136.     public int getPreviousIndex() {  
  137.         int previousIndex = getStartIndex() - pageSize;  
  138.         if (previousIndex < 0)  
  139.             return 0;  
  140.         else  
  141.             return previousIndex;  
  142.     }  
  143.   
  144.     /**  
  145.      * 取总页数.  
  146.      */  
  147.     public long getTotalPageCount() {  
  148.         if (totalCount % pageSize == 0)  
  149.             return totalCount / pageSize;  
  150.         else  
  151.             return totalCount / pageSize + 1;  
  152.     }  
  153.   
  154.     /**  
  155.      * 取该页当前页码,页码从1开始.  
  156.      */  
  157.     public long getCurrentPageNo() {  
  158.         return startIndex / pageSize + 1;  
  159.     }  
  160.   
  161.     /**  
  162.      * 该页是否有下一页.  
  163.      */  
  164.     public boolean hasNextPage() {  
  165.         return this.getCurrentPageNo() < this.getTotalPageCount() - 1;  
  166.     }  
  167.   
  168.     /**  
  169.      * 该页是否有上一页.  
  170.      */  
  171.     public boolean hasPreviousPage() {  
  172.         return this.getCurrentPageNo() > 1;  
  173.     }  
  174. }