另提供IBM 社区基于Hibernate编写的GenericDao参考文章地址

中文版:http://www.ibm.com/developerworks/cn/java/j-genericdao.html

英文版:http://www.ibm.com/developerworks/java/library/j-genericdao.html

结构看图:


HinernateEntityDao和HibernateGenericDao都继承在spring的HibernateDaoSupport


一个提供和实体相关的操作,一个提供和实体类无关的操作。


然后以组合的方式在BaseDao中使用,这样程序中全部使用IBaseDao接口来操作数据,便于修改和维护.


xml配置实用如下:

1. <?xml version="1.0" encoding="UTF-8"?>
2. <beans xmlns="http://www.springframework.org/schema/beans"
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
5.     <!-这个是和实体相关的dao,所以scope是prototype的每个实体对应一个对象->
6. <bean id="hedao"
7. class="com.hibernate.dao.extend.HibernateEntityDao" scope="prototype" lazy-init="true">
8. <property name="sessionFactory">
9. <ref bean="sessionFactory" />
10. </property>
11. </bean>
12.      
13.     <!-这个和具体实体无关,所有dao共享->
14. <bean id="hgdao"
15. class="com.hibernate.dao.generic.HibernateGenericDao">
16. <property name="sessionFactory">
17. <ref bean="sessionFactory" />
18. </property>
19. </bean>
20. <!--使用泛型DAO作为抽象基类-->
21. <bean id="baseDao" class="com.hibernate.dao.base.BaseDao"
22. abstract="true" depends-on="hedao,hgdao">
23. <property name="hedao">
24. <ref bean="hedao" />
25. </property>
26. <property name="hgdao">
27. <ref bean="hgdao" />
28. </property>
29. </bean>
30.      
31. <!-- 配置实体Demodata的DAO -->
32. <bean id="demoDao" parent="baseDao">
33. <constructor-arg>
34. <value>com.hibernate.entityclass.Demodata</value>
35. </constructor-arg>
36. </bean>
37.      
38. </beans>

BaseDao.java

    1. package
    2. import
    3. import
    4. import
    5. import
    6. import
    7. import
    8. import
    9. import
    10. import
    11. /**
    12.  * 提供hibernate dao的所有操作,<br>
    13.  * 实现类由spring注入HibernateEntityDao和HibernateGenericDao来实现
    14.  * 
    15.  */
    16. public class BaseDao<T,PK extends Serializable> implements
    17. protected Class<T> entityClass;// DAO所管理的Entity类型.
    18. private
    19. private
    20.      
    21. public void
    22.         hedao.setEntityClass(entityClass); 
    23. this.hedao = hedao; 
    24.     } 
    25. public void
    26. this.hgdao = hgdao; 
    27.     } 
    28.      
    29. /**
    30.      *让spring提供构造函数注入
    31.      */
    32. public
    33. this.entityClass = type; 
    34.     } 
    35.      
    36. public
    37.      
    38. /**
    39.      * 清除所有对象缓存
    40.      */
    41. public void
    42.          
    43.         hgdao.clear(); 
    44.     } 
    45. /**
    46.      * 创建Criteria对象.
    47.      * @param criterions 可变的Restrictions条件列表
    48.      */
    49. public
    50.          
    51. return
    52.     } 
    53. /**
    54.      * 创建Criteria对象,带排序字段与升降序字段.
    55.      */
    56. public Criteria createCriteria(String orderBy, boolean
    57.             Criterion... criterions) { 
    58.          
    59. return
    60.     } 
    61. /**
    62.      * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
    63.      * 留意可以连续设置,如下:
    64.      * <pre>
    65.      * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
    66.      * </pre>
    67.      * 调用方式如下:
    68.      * <pre>
    69.      *        dao.createQuery(hql)
    70.      *        dao.createQuery(hql,arg0);
    71.      *        dao.createQuery(hql,arg0,arg1);
    72.      *        dao.createQuery(hql,new Object[arg0,arg1,arg2])
    73.      * </pre>
    74.      *
    75.      * @param values 可变参数.
    76.      */
    77. public
    78.          
    79. return
    80.     } 
    81. /**
    82.      * @param hql 查询sql
    83.      * @param start 分页从哪一条数据开始
    84.      * @param pageSize 每一个页面的大小
    85.      * @param values 查询条件
    86.      * @return page对象
    87.      */
    88. public Page dataQuery(String hql, int start, int
    89.          
    90. return
    91.     } 
    92. /**
    93.      * 消除与 Hibernate Session 的关联
    94.      * @param entity
    95.      */
    96. public void
    97.          
    98.         hedao.evict(entity); 
    99.     } 
    100. /**
    101.      * 执行本地sql语句获得标量数值列表
    102.      */
    103. @SuppressWarnings("unchecked") 
    104. public
    105.          
    106. return
    107.     } 
    108. /**
    109.      * 根据hql查询,直接使用HibernateTemplate的find函数.
    110.      * @param values 可变参数
    111.      */
    112. @SuppressWarnings("unchecked") 
    113. public
    114.          
    115. return
    116.     } 
    117. /**
    118.      * 根据属性名和属性值查询对象.
    119.      * @return 符合条件的对象列表
    120.      */
    121. public
    122.          
    123. return
    124.     } 
    125. /**
    126.      * 根据属性名和属性值查询对象,带排序参数.
    127.      */
    128. public
    129. boolean
    130.          
    131. return
    132.     } 
    133. /**
    134.      * 根据属性名和属性值查询唯一对象.
    135.      * @return 符合条件的唯一对象 or null if not found.
    136.      */
    137. public
    138.          
    139. return
    140.     } 
    141. /**
    142.      * 执行一些必须的sql语句把内存中的对象同步到jdbc的链接中
    143.      */
    144. public void
    145.          
    146.         hgdao.flush(); 
    147.     } 
    148.      
    149. /**
    150.      * 根据Serializable类型的id获取实体对象<p/>
    151.      * 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
    152.      * @param id
    153.      */
    154. public
    155.          
    156. return
    157.     } 
    158. /**
    159.      * 获取实体类型的全部对象
    160.      */
    161. public
    162.          
    163. return
    164.     } 
    165. /**
    166.      * 获取全部对象,带排序字段与升降序参数.
    167.      */
    168. public List<T> getAll(String orderBy, boolean
    169.          
    170. return
    171.     } 
    172. /**
    173.      * 直接使用spring提供的HibernateTemplate
    174.      */
    175. public
    176.          
    177. return
    178.     } 
    179. /**
    180.      * 判断对象某些属性的值在数据库中是否唯一.
    181.      *
    182.      * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
    183.      */
    184. public boolean
    185.          
    186. return
    187.     } 
    188. /**
    189.      * 分页查询函数,使用hql.
    190.      *
    191.      * @param pageNo 页号,从1开始.
    192.      */
    193. public Page pagedQuery(String hql, int pageNo, int
    194.             Object... values) { 
    195.          
    196. return
    197.     } 
    198. /**
    199.      * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
    200.      *
    201.      * @param pageNo 页号,从1开始.
    202.      * @return 含总记录数和当前页数据的Page对象.
    203.      */
    204. public Page pagedQuery(Criteria criteria, int pageNo, int
    205.          
    206. return
    207.     } 
    208. /**
    209.      * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
    210.      *
    211.      * @param pageNo 页号,从1开始.
    212.      * @return 含总记录数和当前页数据的Page对象.
    213.      */
    214. public Page pagedQuery(int pageNo, int
    215.          
    216. return
    217.     } 
    218. /**
    219.      * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
    220.      *
    221.      * @param pageNo 页号,从1开始.
    222.      * @return 含总记录数和当前页数据的Page对象.
    223.      */
    224. public Page pagedQuery(int pageNo, int
    225. boolean
    226.          
    227. return
    228.     } 
    229. /**
    230.      * 删除对象. 
    231.      */ 
    232. public void
    233.          
    234.        hedao.remove(entity); 
    235.     } 
    236. /**
    237.      * 根据ID删除对象.
    238.      */
    239. public void
    240.          
    241.         hedao.removeById(id); 
    242.     } 
    243. /**
    244.      * 保存对象.<br>
    245.      * 如果对象已在本session中持久化了,不做任何事。<br>
    246.      * 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>
    247.      * 如果没有持久化标识属性,调用save()。<br>
    248.      * 如果持久化标识表明是一个新的实例化对象,调用save()。<br>
    249.      * 如果是附带版本信息的(<version>或<timestamp>)且版本属性表明为新的实例化对象就save()。<br>
    250.      * 否则调用update()重新关联托管对象
    251.      */
    252. public void
    253.         hedao.save(entity); 
    254.     } 
    255.      
    256. /**
    257.      * 在不同的session中关联修改过的托管对象
    258.      */
    259. public void
    260.          
    261.         hedao.update(entity); 
    262.     } 
    263. }

    1. /**
    2.  * 
    3.  */
    4. package
    5. import
    6. import
    7. import
    8. import
    9. import
    10. import
    11. import
    12. import
    13. /**
    14.  * 提供hibernate dao的所有操作,<br>
    15.  * 实现类由spring注入HibernateEntityDao和HibernateGenericDao来实现
    16.  * 
    17.  */
    18. public interface IBaseDao<T,PK extends
    19.      
    20. /**
    21.      * 获取全部对象
    22.      * 
    23.      * @see HibernateGenericDao#getAll(Class)
    24.      */
    25. public
    26.      
    27. /**
    28.      * 获取全部对象,带排序参数.
    29.      */
    30. public List<T> getAll(String orderBy, boolean
    31.      
    32. /**
    33.      * 根据ID移除对象.
    34.      */
    35. public void
    36.      
    37. /**
    38.      * 取得Entity的Criteria.
    39.      */
    40. public
    41.      
    42. /**
    43.      * 取得Entity的Criteria,带排序参数. 
    44.      */ 
    45. public Criteria createCriteria(String orderBy, boolean
    46.             Criterion... criterions); 
    47.      
    48. /**
    49.      * 根据属性名和属性值查询对象.
    50.      * 
    51.      * @return 符合条件的对象列表
    52.      */
    53. public
    54.      
    55. /**
    56.      * 根据属性名和属性值查询对象,带排序参数.
    57.      * 
    58.      * @return 符合条件的对象列表
    59.      */
    60. public
    61. boolean
    62.      
    63. /**
    64.      * 根据属性名和属性值查询单个对象.
    65.      * 
    66.      * @return 符合条件的唯一对象 or null
    67.      */
    68. public
    69.      
    70. /**
    71.      * 判断对象某些属性的值在数据库中唯一.
    72.      * 
    73.      * @param uniquePropertyNames
    74.      *            在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
    75.      * @see HibernateGenericDao#isUnique(Class,Object,String)
    76.      */
    77. public boolean
    78.      
    79. /**
    80.      * 消除与 Hibernate Session 的关联
    81.      * 
    82.      */
    83. public void
    84.      
    85.      
    86. /**
    87.      * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
    88.      */
    89. public
    90.      
    91. /**
    92.      * 保存对象.
    93.      */
    94. public void
    95.      
    96. /**
    97.      * 删除对象.
    98.      */
    99. public void
    100.      
    101. public void
    102.      
    103. public void
    104.      
    105. /**
    106.      * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
    107.      * 留意可以连续设置,如下:
    108.      * <pre>
    109.      * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
    110.      * </pre>
    111.      * 调用方式如下:
    112.      * <pre>
    113.      *        dao.createQuery(hql)
    114.      *        dao.createQuery(hql,arg0);
    115.      *        dao.createQuery(hql,arg0,arg1);
    116.      *        dao.createQuery(hql,new Object[arg0,arg1,arg2])
    117.      * </pre>
    118.      *
    119.      * @param values 可变参数.
    120.      */
    121. public
    122.      
    123.      
    124. /**
    125.      * 根据hql查询,直接使用HibernateTemplate的find函数.
    126.      */
    127. @SuppressWarnings("unchecked") 
    128. public
    129.      
    130. /**
    131.      * 分页查询函数,使用hql.
    132.      *
    133.      * @param pageNo 页号,从1开始.
    134.      */
    135. public Page pagedQuery(String hql, int pageNo, int
    136.      
    137. /**
    138.      * @param hql 查询sql
    139.      * @param start 分页从哪一条数据开始
    140.      * @param pageSize 每一个页面的大小
    141.      * @param values 查询条件
    142.      * @return page对象
    143.      */
    144. public Page dataQuery(String hql, int start, int
    145.      
    146. /**
    147.      * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
    148.      *
    149.      * @param pageNo 页号,从1开始.
    150.      * @return 含总记录数和当前页数据的Page对象.
    151.      */
    152. public Page pagedQuery(Criteria criteria, int pageNo, int
    153.      
    154. /**
    155.      * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
    156.      *
    157.      * @param pageNo 页号,从1开始.
    158.      * @return 含总记录数和当前页数据的Page对象.
    159.      */
    160. public Page pagedQuery(int pageNo, int
    161.      
    162. /**
    163.      * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
    164.      *
    165.      * @param pageNo 页号,从1开始.
    166.      * @return 含总记录数和当前页数据的Page对象.
    167.      */
    168. public Page pagedQuery(int pageNo, int pageSize, String orderBy, boolean
    169.                Criterion... criterions); 
    170.      
    171. @SuppressWarnings("unchecked") 
    172. public
    173.      
    174. public
    175.      
    176. /**
    177.      * 在不同的session中关联修改过的托管对象
    178.      */
    179. public void
    180. }

    1. /**
    2.  * 
    3.  */
    4. package
    5. import
    6. import
    7. import
    8. import
    9. import
    10. import
    11. import
    12. import
    13. import
    14. import
    15. import
    16. import
    17. import
    18. import
    19. import
    20. import
    21. import
    22. import
    23. import
    24. import
    25. /**
    26.  * 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类. <p/> 
    27.  * 子类只要在类定义时指定所管理Entity的Class,
    28.  * 即拥有对单个Entity对象的CRUD操作.
    29.  * 
    30.  * @see    继承自spring的HibernateDaoSupport
    31.  */
    32. public class HibernateEntityDao<T,PK extends Serializable> extends HibernateDaoSupport implements
    33. protected Class<T> entityClass;// DAO所管理的Entity类型.
    34. public void
    35. this.entityClass=type; 
    36.     } 
    37. /**
    38.      * 在构造函数中将泛型T.class赋给entityClass.
    39.      */
    40. public
    41. //entityClass = GenericsUtils.getSuperClassGenricType(getClass());
    42.     } 
    43. /**
    44.      * 取得entityClass.JDK1.4不支持泛型的子类可以抛开Class<T> entityClass,重载此函数达到相同效果。
    45.      */
    46. protected
    47. return
    48.     } 
    49.      
    50. /**
    51.      * 根据Serializable类型的id获取实体对象<p/>
    52.      * 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
    53.      * @param id
    54.      */
    55. @SuppressWarnings("unchecked") 
    56. public
    57.          
    58. return
    59.     } 
    60.      
    61. /**
    62.      * 获取实体类型的全部对象 
    63.      */ 
    64. @SuppressWarnings("unchecked") 
    65. public
    66. return
    67.     } 
    68.      
    69. /**
    70.      * 获取全部对象,带排序字段与升降序参数. 
    71.      */ 
    72. @SuppressWarnings("unchecked") 
    73. public  List<T> getAll(String orderBy, boolean
    74.         Assert.hasText(orderBy); 
    75. if
    76. return
    77.                     DetachedCriteria.forClass(getEntityClass()).addOrder(Order.asc(orderBy))); 
    78. else
    79. return
    80.                     DetachedCriteria.forClass(getEntityClass()).addOrder(Order.desc(orderBy))); 
    81.     } 
    82. /**
    83.      * 删除对象.
    84.      */
    85. public void
    86.         getHibernateTemplate().delete(entity); 
    87.     } 
    88. /**
    89.      * 根据ID删除对象.
    90.      */
    91. public void
    92.          
    93.         remove(get(id)); 
    94.     } 
    95. /**
    96.      * 保存对象.<br>
    97.      * 如果对象已在本session中持久化了,不做任何事。<br>
    98.      * 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>
    99.      * 如果没有持久化标识属性,调用save()。<br>
    100.      * 如果持久化标识表明是一个新的实例化对象,调用save()。<br>
    101.      * 如果是附带版本信息的(<version>或<timestamp>)且版本属性表明为新的实例化对象就save()。<br>
    102.      * 否则调用update()重新关联托管对象
    103.      */
    104. public void
    105.        getHibernateTemplate().saveOrUpdate(entity); 
    106.     } 
    107. /**
    108.      * 在不同的session中关联修改过的托管对象
    109.      */
    110. public void
    111.        getHibernateTemplate().update(entity); 
    112.     } 
    113.      
    114. /**
    115.      * 消除与 Hibernate Session 的关联
    116.      * @param entity
    117.      */
    118. public void
    119.         getHibernateTemplate().evict(entity); 
    120.     } 
    121.      
    122. /**
    123.      * 创建Criteria对象.
    124.      * @param criterions 可变的Restrictions条件列表
    125.      */
    126. public
    127.         Criteria criteria = getSession().createCriteria(getEntityClass()); 
    128. for
    129.             criteria.add(c); 
    130.         } 
    131. return
    132.     } 
    133. /**
    134.      * 创建Criteria对象,带排序字段与升降序字段.
    135.      */
    136. public  Criteria createCriteria(String orderBy, boolean
    137.         Assert.hasText(orderBy); 
    138.         Criteria criteria = createCriteria(criterions); 
    139. if
    140.             criteria.addOrder(Order.asc(orderBy)); 
    141. else
    142.             criteria.addOrder(Order.desc(orderBy)); 
    143. return
    144.     } 
    145.      
    146. /**
    147.      * 根据属性名和属性值查询对象.
    148.      * @return 符合条件的对象列表
    149.      */
    150. @SuppressWarnings("unchecked") 
    151. public
    152.         Assert.hasText(propertyName); 
    153. return
    154.     } 
    155.      
    156. /**
    157.      * 根据属性名和属性值查询对象,带排序参数. 
    158.      */ 
    159. @SuppressWarnings("unchecked") 
    160. public  List<T> findBy(String propertyName, Object value, String orderBy, boolean
    161.         Assert.hasText(propertyName); 
    162.         Assert.hasText(orderBy); 
    163. return
    164.     } 
    165.      
    166. /**
    167.      * 根据属性名和属性值查询唯一对象.
    168.      * @return 符合条件的唯一对象 or null if not found.
    169.      */
    170. @SuppressWarnings("unchecked") 
    171. public
    172.         Assert.hasText(propertyName); 
    173. return
    174.     } 
    175.      
    176. /**
    177.      * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
    178.      *
    179.      * @param pageNo 页号,从1开始.
    180.      * @return 含总记录数和当前页数据的Page对象.
    181.      */
    182. @SuppressWarnings("unchecked") 
    183. public Page pagedQuery(Criteria criteria, int pageNo, int
    184.         Assert.notNull(criteria); 
    185. 1, "pageNo should start from 1"); 
    186.         CriteriaImpl impl = (CriteriaImpl) criteria; 
    187. // 先把Projection和OrderBy条件取出来,清空两者来执行Count操作
    188.         Projection projection = impl.getProjection(); 
    189.         List<CriteriaImpl.OrderEntry> orderEntries; 
    190. try
    191. "orderEntries"); 
    192. "orderEntries", new
    193. catch
    194. throw new InternalError(" Runtime Exception impossibility throw "); 
    195.         } 
    196. // 执行查询
    197. int
    198. // 将之前的Projection和OrderBy条件重新设回去
    199.         criteria.setProjection(projection); 
    200. if (projection == null) { 
    201.             criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY); 
    202.         } 
    203. try
    204. "orderEntries", orderEntries); 
    205. catch
    206. throw new InternalError(" Runtime Exception impossibility throw "); 
    207.         } 
    208. // 返回分页对象
    209. if (totalCount < 1) 
    210. return new
    211. int
    212.         List list = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list(); 
    213. return new
    214.     } 
    215.      
    216. /**
    217.      * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
    218.      *
    219.      * @param pageNo 页号,从1开始.
    220.      * @return 含总记录数和当前页数据的Page对象.
    221.      */
    222. public Page pagedQuery(int pageNo, int
    223.         Criteria criteria = createCriteria(criterions); 
    224. return
    225.     } 
    226.      
    227. /**
    228.      * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
    229.      *
    230.      * @param pageNo 页号,从1开始.
    231.      * @return 含总记录数和当前页数据的Page对象.
    232.      */
    233. public Page pagedQuery(int pageNo, int pageSize, String orderBy, boolean
    234.                            Criterion... criterions) { 
    235.         Criteria criteria = createCriteria(orderBy, isAsc, criterions); 
    236. return
    237.     } 
    238.      
    239. /**
    240.      * 判断对象某些属性的值在数据库中是否唯一.
    241.      *
    242.      * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
    243.      */
    244. public boolean
    245.         Assert.hasText(uniquePropertyNames); 
    246.         Criteria criteria = createCriteria().setProjection(Projections.rowCount()); 
    247. ","); 
    248. try
    249. // 循环加入唯一列
    250. for
    251.                 criteria.add(Restrictions.eq(name, PropertyUtils.getProperty(entity, name))); 
    252.             } 
    253. // 以下代码为了如果是update的情况,排除entity自身.
    254.             String idName = getIdName(getEntityClass()); 
    255. // 取得entity的主键值
    256.             PK id = getId(getEntityClass(), entity); 
    257. // 如果id!=null,说明对象已存在,该操作为update,加入排除自身的判断
    258. if (id != null) 
    259.                 criteria.add(Restrictions.not(Restrictions.eq(idName, id))); 
    260. catch
    261.             ReflectionUtils.handleReflectionException(e); 
    262.         } 
    263. return (Integer) criteria.uniqueResult() == 0; 
    264.     } 
    265.      
    266. /**
    267.      * 取得对象的主键值,辅助函数.
    268.      */
    269. @SuppressWarnings("unchecked") 
    270. public  PK getId(Class<T> entityClass, T entity) throws
    271.             InvocationTargetException { 
    272.         Assert.notNull(entity); 
    273.         Assert.notNull(entityClass); 
    274. return
    275.     } 
    276. /**
    277.      * 取得对象的主键名,辅助函数. 
    278.      */ 
    279. public
    280.         Assert.notNull(clazz); 
    281.         ClassMetadata meta = getSessionFactory().getClassMetadata(clazz); 
    282. "Class " + clazz + " not define in hibernate session factory."); 
    283.         String idName = meta.getIdentifierPropertyName(); 
    284. " has no identifier property define."); 
    285. return
    286.     } 
    287. }



    1. package
    2. import
    3. import
    4. /**
    5.  * 针对单个Entity对象的CRUD操作定义.
    6.  */
    7. public interface IEntityDao<T,PK extends
    8.     T get(PK id); 
    9.     List<T> getAll(); 
    10. void
    11. void
    12. void
    13.      
    14. void
    15. /**
    16.      * 获取Entity对象的主键名.
    17.      */
    18.     String getIdName(Class<T> clazz); 
    19. }

    1. /**
    2.  * 
    3.  */
    4. package
    5. import
    6. import
    7. import
    8. import
    9. import
    10. import
    11. import
    12. /**
    13.  * 继承自spring的HibernateDaoSupport<br>
    14.  * 提供了和具体实体类无关的数据库操作,如分页函数和若干便捷查询方法
    15.  * @see    HibernateDaoSupport
    16.  */
    17. public class HibernateGenericDao extends
    18. /**
    19.      * 分页查询函数,使用hql.
    20.      *
    21.      * @param pageNo 页号,从1开始.
    22.      */
    23. @SuppressWarnings("unchecked") 
    24. public Page pagedQuery(String hql, int pageNo, int
    25.         Assert.hasText(hql); 
    26. 1, "pageNo should start from 1"); 
    27. // Count查询
    28. " select count (*) "
    29.         List countlist = getHibernateTemplate().find(countQueryString, values); 
    30. long totalCount = (Long) countlist.get(0); 
    31. if (totalCount < 1) 
    32. return new
    33. // 实际查询返回分页对象
    34. int
    35.         Query query = createQuery(hql, values); 
    36.         List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list(); 
    37. return new
    38.     } 
    39.      
    40. /**
    41.      * @param hql 查询sql
    42.      * @param start 分页从哪一条数据开始
    43.      * @param pageSize 每一个页面的大小
    44.      * @param values 查询条件
    45.      * @return page对象
    46.      */
    47. @SuppressWarnings("unchecked") 
    48. public Page dataQuery(String hql, int start, int
    49.         Assert.hasText(hql); 
    50. // Count查询
    51. " select count (*) "
    52.         List countlist = getHibernateTemplate().find(countQueryString, values); 
    53. long totalCount = (Long) countlist.get(0); 
    54. if (totalCount < 1) 
    55. return new
    56. // 实际查询返回分页对象
    57. int
    58.         Query query = createQuery(hql, values); 
    59.         List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list(); 
    60. return new
    61.      } 
    62.      
    63. /**
    64.      * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
    65.      * 留意可以连续设置,如下:
    66.      * <pre>
    67.      * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
    68.      * </pre>
    69.      * 调用方式如下:
    70.      * <pre>
    71.      *        dao.createQuery(hql)
    72.      *        dao.createQuery(hql,arg0);
    73.      *        dao.createQuery(hql,arg0,arg1);
    74.      *        dao.createQuery(hql,new Object[arg0,arg1,arg2])
    75.      * </pre>
    76.      *
    77.      * @param values 可变参数.
    78.      */
    79. public
    80.         Assert.hasText(hql); 
    81.         Query query = getSession().createQuery(hql); 
    82. for (int i = 0; i < values.length; i++) { 
    83.             query.setParameter(i, values[i]); 
    84.         } 
    85. return
    86.     } 
    87.      
    88. /**
    89.      * 根据hql查询,直接使用HibernateTemplate的find函数.
    90.      * @param values 可变参数
    91.      */
    92. @SuppressWarnings("unchecked") 
    93. public
    94.         Assert.hasText(hql); 
    95. return
    96.     } 
    97.      
    98.      
    99. /**
    100.      * 执行一些必须的sql语句把内存中的对象同步到jdbc的链接中
    101.      */
    102. public void
    103.         getHibernateTemplate().flush(); 
    104.     } 
    105.      
    106. /**
    107.      * 清除所有对象缓存
    108.      */
    109. public void
    110.         getHibernateTemplate().clear(); 
    111.     } 
    112.      
    113. /**
    114.      * 执行本地sql语句获得标量数值列表
    115.      */
    116. @SuppressWarnings("unchecked") 
    117. public
    118. return
    119.     } 
    120. /**
    121.      * 去除hql的select 子句,未考虑union的情况,用于pagedQuery.
    122.      */
    123. private static
    124.         Assert.hasText(hql); 
    125. int beginPos = hql.toLowerCase().indexOf("from"); 
    126. 1, " hql : " + hql + " must has a keyword 'from'"); 
    127. return
    128.     } 
    129.      
    130. /**
    131.      * 去除hql的orderby 子句,用于pagedQuery.
    132.      */
    133. private static
    134.         Assert.hasText(hql); 
    135. "order//s*by[//w|//W|//s|//S]*", Pattern.CASE_INSENSITIVE); 
    136.         Matcher m = p.matcher(hql); 
    137. new
    138. while
    139. ""); 
    140.         } 
    141.         m.appendTail(sb); 
    142. return
    143.     } 
    144. }