以前从springside2.0上搞下来的很好用的,基本实现dao零编码只要配置xml文件就行了。

先看图:

一共4层,com.demonstration.hibernate.basedao是我加的用来进一步解耦hibernate和spring的耦合。 原来的官方解释如下: SpringSide对Hibernate做了三层封装:

第一层:HibernateGenericDao,基于spring的HibernateDaoSupport,但加入了分页函数与各种Finder函数,并使用泛型避免了返回值强制类型转换。

第二层:HibernateEntityDao,基于HibernateGenericDao,用泛型声明Dao所管理的Entity类,默认拥有该entity的CRUD方法。

第三层:HibernateExtendDao,基于HibernateEntityDao,主要扩展各种选择性的功能。

关于三个类的详细注解请看JavaDoc,大致描述如下:

1 HibernateGenericDao    在Spring HibernateDaoSupport基础上封装的DAO,功能如下:

1.应用泛型:使得find(), get() 这些函数不再返回Object,而是返回T,不再需要强制类型转换。

2.提供各种finder的简便函数       应用了JDK5可变参数的hsql查询函数:List find(String hql, Object... values),支持find(hql),find(hql, param1); find(hql,param1,param2);find(hql,new Object[] {param1,param2}) 四种接口。

简单查询的简化函数:findBy(Class entityClass,String name,Object value) ,findUniqueBy(Class entityClass,String name, Object value),findByLike(Class entityClass,String name,Object value)

3.获得设置好的Query和Criteria:createQuery(String hql,Object... values)  和 createCriteria(Class<T> entityClass,Criterion... criterions)

Spring并没有很好的接口封装支持firstResult, maxResult, fetchsize,cache,cacheRegion 等多个查询参数,所以springside宁愿返回已设置好查询条件的Query和Criteria,让大家继续剩下的参数设置,最后再执行 list(),注意那几个参数可以连续设置的,如:

createQuery(hql,param1).setFirstResult(10).setMaxResult(20).list();   4.分页函数:Page pagedQuery(Criteria criteria, int pageNo, int pageSize) 和Page pagedQuery(String hql, int pageNo, int pageSize, Object... args)

Page是SpringSide自行封装的一个典型Page类,pagedQuery与hibernate自身分页查询的差别是先运行一次count,获得符合条件的总记录数。

如果查询不需要总记录数,用普通的hibernate API,加上setFirstResult(),setMaxResult()就解决,不需要pagedQuery()。

5.判别对象属性在数据库中唯一的函数:isUnique(Class<T> entityClass,Object entity,String names)。

2. HibernateEntityDao     所有UserManager, ProductManager之类只管理一类对象的Manager类的基类,只需要在类定义处声明Entity类型即可

public class BookManager extends HibernateEntityDao<Book> { }  通过<Book>的定义,避免了HibernateGenericDao类各方法中必有的Class entityClass参数。

如果需要操作其他的Entity,比如BookManager可能需要处理Category(图书目录),可以注入CategoryManager。无需担心事务的问题,JavaEE的默认事务模型已能很好处理。

如果没有对应的CategoryManager,或者各种原因不想注入的话,可以使用BookManager继承自 HibernateGenericDao的带entityClass参数的函数来操作Category的增删改,如Category category= this.get(Category.class, 1);

3. HibernateExtendDao       此类演示SpringSide 所作的一些扩展,大家可以按照自己的需要进行修改和扩展。

1. 支持对象不能被直接删除,只能设置状态列为无效。         接口UndeleteableEntityOperation,定义了要支持此功能必须实现的函数。

可以有接口(UndeletableEntity)和annotation(@Undeletable)两种形式来定义无效列,annotation列形式还可以定义标识对象已删除的状态属性的名称,用接口则必须实现setStatus()接口,在里面操作实际的状态属性。

第四层就是把HibernateEntityDao和HibernateExtendDao以属性注入的方式注入到basedao,IBasedao就全局接口程序中使用的就是它,这个接口的实现全调用HibernateEntityDao和HibernateExtendDao的方法。方便以后的更改和替换,这样IBasedao接口不变就不要修改业务层的代码了。

代码如下(从下到上):

  1. Page.java
  2. package com.demonstration.hibernate.dao.support;
  3. import java.io.Serializable;
  4. import java.util.ArrayList;
  5. /**
  6. * 分页对象. 包含当前页数据及分页信息如总记录数.
  7. *
  8. * @author springside
  9. *
  10. */
  11. @SuppressWarnings("serial")
  12. public class Page implements Serializable {
  13. private static int DEFAULT_PAGE_SIZE = 20;
  14. private int pageSize = DEFAULT_PAGE_SIZE; // 每页的记录数
  15. private long start; // 当前页第一条数据在List中的位置,从0开始
  16. private Object data; // 当前页中存放的记录,类型一般为List
  17. private long totalCount; // 总记录数
  18. /**
  19. * 构造方法,只构造空页.
  20. */
  21. @SuppressWarnings("unchecked")
  22. public Page() {
  23. this(0, 0, DEFAULT_PAGE_SIZE, new ArrayList());
  24. }
  25. /**
  26. * 默认构造方法.
  27. *
  28. * @param start 本页数据在数据库中的起始位置
  29. * @param totalSize 数据库中总记录条数
  30. * @param pageSize 本页容量
  31. * @param data 本页包含的数据
  32. */
  33. public Page(long start, long totalSize, int pageSize, Object data) {
  34. this.pageSize = pageSize;
  35. this.start = start;
  36. this.totalCount = totalSize;
  37. this.data = data;
  38. }
  39. /**
  40. * 取总记录数.
  41. */
  42. public long getTotalCount() {
  43. return this.totalCount;
  44. }
  45. /**
  46. * 取总页数.
  47. */
  48. public long getTotalPageCount() {
  49. if (totalCount % pageSize == 0)
  50. return totalCount / pageSize;
  51. else
  52. return totalCount / pageSize + 1;
  53. }
  54. /**
  55. * 取每页数据容量.
  56. */
  57. public int getPageSize() {
  58. return pageSize;
  59. }
  60. /**
  61. * 取当前页中的记录.
  62. */
  63. public Object getResult() {
  64. return data;
  65. }
  66. /**
  67. * 取该页当前页码,页码从1开始.
  68. */
  69. public long getCurrentPageNo() {
  70. return start / pageSize + 1;
  71. }
  72. /**
  73. * 该页是否有下一页.
  74. */
  75. public boolean hasNextPage() {
  76. return this.getCurrentPageNo() < this.getTotalPageCount() - 1;
  77. }
  78. /**
  79. * 该页是否有上一页.
  80. */
  81. public boolean hasPreviousPage() {
  82. return this.getCurrentPageNo() > 1;
  83. }
  84. /**
  85. * 获取任一页第一条数据在数据集的位置,每页条数使用默认值.
  86. *
  87. * @see #getStartOfPage(int,int)
  88. */
  89. protected static int getStartOfPage(int pageNo) {
  90. return getStartOfPage(pageNo, DEFAULT_PAGE_SIZE);
  91. }
  92. /**
  93. * 获取任一页第一条数据在数据集的位置.
  94. *
  95. * @param pageNo 从1开始的页号
  96. * @param pageSize 每页记录条数
  97. * @return 该页第一条数据
  98. */
  99. public static int getStartOfPage(int pageNo, int pageSize) {
  100. return (pageNo - 1) * pageSize;
  101. }
  102. }
  103. GenericsUtils.java
  104. package com.demonstration.hibernate.dao.support;
  105. import java.lang.reflect.ParameterizedType;
  106. import java.lang.reflect.Type;
  107. import org.apache.commons.logging.Log;
  108. import org.apache.commons.logging.LogFactory;
  109. /**
  110. * Generics的util类.
  111. *
  112. * @author springside
  113. *
  114. */
  115. public class GenericsUtils {
  116. private static final Log log = LogFactory.getLog(GenericsUtils.class);
  117. private GenericsUtils() {
  118. }
  119. /**
  120. * 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends GenricManager<Book>
  121. *
  122. * @param clazz The class to introspect
  123. * @return the first generic declaration, or <code>Object.class</code> if cannot be determined
  124. */
  125. @SuppressWarnings("unchecked")
  126. public static Class getSuperClassGenricType(Class clazz) {
  127. return getSuperClassGenricType(clazz, 0);
  128. }
  129. /**
  130. * 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends GenricManager<Book>
  131. *
  132. * @param clazz clazz The class to introspect
  133. * @param index the Index of the generic ddeclaration,start from 0.
  134. * @return the index generic declaration, or <code>Object.class</code> if cannot be determined
  135. */
  136. @SuppressWarnings("unchecked")
  137. public static Class getSuperClassGenricType(Class clazz, int index) {
  138. Type genType = clazz.getGenericSuperclass();
  139. if (!(genType instanceof ParameterizedType)) {
  140. log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
  141. return Object.class;
  142. }
  143. Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
  144. if (index >= params.length || index < 0) {
  145. log.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
  146. + params.length);
  147. return Object.class;
  148. }
  149. if (!(params[index] instanceof Class)) {
  150. log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
  151. return Object.class;
  152. }
  153. return (Class) params[index];
  154. }
  155. }
  156.  
  157. BeanUtils.java
  158.  
  159. package com.demonstration.hibernate.dao.support;
  160. import java.lang.reflect.Field;
  161. import java.lang.reflect.Method;
  162. import java.util.ArrayList;
  163. import java.util.List;
  164. import org.apache.commons.lang.StringUtils;
  165. import org.apache.commons.logging.Log;
  166. import org.apache.commons.logging.LogFactory;
  167. import org.springframework.util.Assert;
  168. import org.springframework.util.ReflectionUtils;
  169. /**
  170. * 扩展Apache Commons BeanUtils, 提供一些反射方面缺失功能的封装.
  171. * @author springside
  172. *
  173. */
  174. public class BeanUtils extends org.apache.commons.beanutils.BeanUtils {
  175. protected static final Log logger = LogFactory.getLog(BeanUtils.class);
  176. private BeanUtils() {
  177. }
  178. /**
  179. * 循环向上转型,获取对象的DeclaredField.
  180. *
  181. * @throws NoSuchFieldException 如果没有该Field时抛出.
  182. */
  183. public static Field getDeclaredField(Object object, String propertyName) throws NoSuchFieldException {
  184. Assert.notNull(object);
  185. Assert.hasText(propertyName);
  186. return getDeclaredField(object.getClass(), propertyName);
  187. }
  188. /**
  189. * 循环向上转型,获取对象的DeclaredField.
  190. *
  191. * @throws NoSuchFieldException 如果没有该Field时抛出.
  192. */
  193. @SuppressWarnings("unchecked")
  194. public static Field getDeclaredField(Class clazz, String propertyName) throws NoSuchFieldException {
  195. Assert.notNull(clazz);
  196. Assert.hasText(propertyName);
  197. for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
  198. try {
  199. return superClass.getDeclaredField(propertyName);
  200. } catch (NoSuchFieldException e) {
  201. // Field不在当前类定义,继续向上转型
  202. }
  203. }
  204. throw new NoSuchFieldException("No such field: " + clazz.getName() + '.' + propertyName);
  205. }
  206. /**
  207. * 暴力获取对象变量值,忽略private,protected修饰符的限制.
  208. *
  209. * @throws NoSuchFieldException 如果没有该Field时抛出.
  210. */
  211. public static Object forceGetProperty(Object object, String propertyName) throws NoSuchFieldException {
  212. Assert.notNull(object);
  213. Assert.hasText(propertyName);
  214. Field field = getDeclaredField(object, propertyName);
  215. boolean accessible = field.isAccessible();
  216. field.setAccessible(true);
  217. Object result = null;
  218. try {
  219. result = field.get(object);
  220. } catch (IllegalAccessException e) {
  221. logger.info("error wont' happen");
  222. }
  223. field.setAccessible(accessible);
  224. return result;
  225. }
  226. /**
  227. * 暴力设置对象变量值,忽略private,protected修饰符的限制.
  228. *
  229. * @throws NoSuchFieldException 如果没有该Field时抛出.
  230. */
  231. public static void forceSetProperty(Object object, String propertyName, Object newValue)
  232. throws NoSuchFieldException {
  233. Assert.notNull(object);
  234. Assert.hasText(propertyName);
  235. Field field = getDeclaredField(object, propertyName);
  236. boolean accessible = field.isAccessible();
  237. field.setAccessible(true);
  238. try {
  239. field.set(object, newValue);
  240. } catch (IllegalAccessException e) {
  241. logger.info("Error won't happen");
  242. }
  243. field.setAccessible(accessible);
  244. }
  245. /**
  246. * 暴力调用对象函数,忽略private,protected修饰符的限制.
  247. *
  248. * @throws NoSuchMethodException 如果没有该Method时抛出.
  249. */
  250. @SuppressWarnings("unchecked")
  251. public static Object invokePrivateMethod(Object object, String methodName, Object... params)
  252. throws NoSuchMethodException {
  253. Assert.notNull(object);
  254. Assert.hasText(methodName);
  255. Class[] types = new Class[params.length];
  256. for (int i = 0; i < params.length; i++) {
  257. types[i] = params[i].getClass();
  258. }
  259. Class clazz = object.getClass();
  260. Method method = null;
  261. for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
  262. try {
  263. method = superClass.getDeclaredMethod(methodName, types);
  264. break;
  265. } catch (NoSuchMethodException e) {
  266. // 方法不在当前类定义,继续向上转型
  267. }
  268. }
  269. if (method == null)
  270. throw new NoSuchMethodException("No Such Method:" + clazz.getSimpleName() + methodName);
  271. boolean accessible = method.isAccessible();
  272. method.setAccessible(true);
  273. Object result = null;
  274. try {
  275. result = method.invoke(object, params);
  276. } catch (Exception e) {
  277. ReflectionUtils.handleReflectionException(e);
  278. }
  279. method.setAccessible(accessible);
  280. return result;
  281. }
  282. /**
  283. * 按Filed的类型取得Field列表.
  284. */
  285. @SuppressWarnings("unchecked")
  286. public static List<Field> getFieldsByType(Object object, Class type) {
  287. List<Field> list = new ArrayList<Field>();
  288. Field[] fields = object.getClass().getDeclaredFields();
  289. for (Field field : fields) {
  290. if (field.getType().isAssignableFrom(type)) {
  291. list.add(field);
  292. }
  293. }
  294. return list;
  295. }
  296. /**
  297. * 按FiledName获得Field的类型.
  298. */
  299. @SuppressWarnings("unchecked")
  300. public static Class getPropertyType(Class type, String name) throws NoSuchFieldException {
  301. return getDeclaredField(type, name).getType();
  302. }
  303. /**
  304. * 获得field的getter函数名称.
  305. */
  306. @SuppressWarnings("unchecked")
  307. public static String getGetterName(Class type, String fieldName) {
  308. Assert.notNull(type, "Type required");
  309. Assert.hasText(fieldName, "FieldName required");
  310. if (type.getName().equals("boolean")) {
  311. return "is" + StringUtils.capitalize(fieldName);
  312. } else {
  313. return "get" + StringUtils.capitalize(fieldName);
  314. }
  315. }
  316. /**
  317. * 获得field的getter函数,如果找不到该方法,返回null.
  318. */
  319. @SuppressWarnings("unchecked")
  320. public static Method getGetterMethod(Class type, String fieldName) {
  321. try {
  322. return type.getMethod(getGetterName(type, fieldName));
  323. } catch (NoSuchMethodException e) {
  324. logger.error(e.getMessage(), e);
  325. }
  326. return null;
  327. }
  328. }
  329.  
  330. IUndeleteableEntityOperation.java
  331.  
  332. package com.demonstration.hibernate.dao.extend;
  333. import java.util.List;
  334. import org.hibernate.criterion.Criterion;
  335. /**
  336. * 定义如果支持Entity不被直接删除必须支持的Operation.
  337. *
  338. * @author springside
  339. *
  340. */
  341. public interface IUndeleteableEntityOperation<T> {
  342. /*
  343. * Undelete Entity用到的几个常量,因为要同时兼顾Interface与Annotation,所以集中放此.
  344. */
  345. String UNVALID_VALUE = "-1";
  346. String NORMAL_VALUE = "0";
  347. String STATUS = "status";
  348. /**
  349. * 取得所有状态为有效的对象.
  350. */
  351. List<T> getAllValid();
  352. /**
  353. * 删除对象,但如果是Undeleteable的entity,设置对象的状态而不是直接删除.
  354. */
  355. void remove(Object entity);
  356. /**
  357. * 获取过滤已删除对象的hql条件语句.
  358. */
  359. String getUnDeletableHQL();
  360. /**
  361. * 获取过滤已删除对象的Criterion条件语句.
  362. */
  363. Criterion getUnDeletableCriterion();
  364. }
  365.  
  366. IUndeletableEntity.java
  367. package com.demonstration.hibernate.dao.extend;
  368. /**
  369. * 标识商业对象不能被删除,只能被设为无效的接口.
  370. *
  371. * @author springside
  372. *
  373. */
  374. public interface IUndeletableEntity {
  375. void setStatus(String status);
  376. }
  377.  
  378. IUndeletable.java
  379. package com.demonstration.hibernate.dao.extend;
  380. import java.lang.annotation.ElementType;
  381. import java.lang.annotation.Retention;
  382. import java.lang.annotation.RetentionPolicy;
  383. import java.lang.annotation.Target;
  384. /**
  385. * 标识商业对象不能被删除,只能被设为无效的Annoation.
  386. * <p/>
  387. * 相比inferface的标示方式,annotation 方式更少侵入性,可以定义任意属性代表status,而默认为status属性.
  388. */
  389. @Target({ElementType.TYPE})
  390. @Retention(RetentionPolicy.RUNTIME)
  391. public @interface IUndeletable {
  392. String status() default IUndeleteableEntityOperation.STATUS;
  393. }
  394.  
  395. HibernateEntityExtendDao.java
  396. package com.demonstration.hibernate.dao.extend;
  397. import java.util.List;
  398. import java.util.Map;
  399. import org.apache.commons.beanutils.PropertyUtils;
  400. import org.hibernate.Criteria;
  401. import org.hibernate.criterion.Criterion;
  402. import org.hibernate.criterion.Restrictions;
  403. import org.springframework.util.Assert;
  404. import org.springframework.util.ReflectionUtils;
  405. import com.demonstration.hibernate.dao.HibernateEntityDao;
  406.  
  407. /**
  408. * 加强版的entity dao.
  409. * <p>自动处理Undeletable Entity.<br>
  410. * Undeletable Entity 在删除时只把状态设为无效,不会真正执行删除.<br>
  411. * Undeletable Entity 可以通过annotation或接口两种形式来声明.<br>
  412. * 其中annotation模式不限制状态列的属性名必须为"status",可以用注释来确定任意属性为状态属性.<br>
  413. * </p>
  414. *
  415. * @author springside
  416. *
  417. * @see HibernateEntityDao
  418. * @see EntityInfo
  419. * @see IUndeleteableEntityOperation
  420. * @see IUndeletable
  421. * @see IUndeletableEntity
  422. */
  423. @SuppressWarnings("unchecked")
  424. public class HibernateEntityExtendDao<T> extends HibernateEntityDao<T> implements IUndeleteableEntityOperation<T> {
  425. /**
  426. * 保存所管理的Entity的信息.
  427. */
  428. protected EntityInfo entityInfo;
  429. /**
  430. * 构造函数,初始化entity信息.
  431. */
  432. public HibernateEntityExtendDao() {
  433. entityInfo = new EntityInfo(entityClass);
  434. }
  435. /**
  436. * 取得所有状态为有效的对象.
  437. *
  438. * @see IUndeleteableEntityOperation#getAllValid()
  439. */
  440. public List<T> getAllValid() {
  441. Criteria criteria = createCriteria();
  442. if (entityInfo.isUndeletable)
  443. criteria.add(getUnDeletableCriterion());
  444. return criteria.list();
  445. }
  446. /**
  447. * 获取过滤已删除对象的hql条件语句.
  448. *
  449. * @see IUndeleteableEntityOperation#getUnDeletableHQL()
  450. */
  451. public String getUnDeletableHQL() {
  452. return entityInfo.statusProperty + "<>" + UNVALID_VALUE;
  453. }
  454. /**
  455. * 获取过滤已删除对象的Criterion条件语句.
  456. *
  457. * @see UndeleteableEntityOperation#
  458. */
  459. public Criterion getUnDeletableCriterion() {
  460. return Restrictions.not(Restrictions.eq(entityInfo.statusProperty, UNVALID_VALUE));
  461. }
  462. /**
  463. * 重载保存函数,在保存前先调用onValid(T),进行书名不重复等数据库相关的校验.
  464. *
  465. * @see #onValid(Object)
  466. * @see HibernateEntityDao#save(Object)
  467. */
  468. @Override
  469. public void save(Object entity) {
  470. Assert.isInstanceOf(getEntityClass(), entity);
  471. onValid((T) entity);
  472. super.save(entity);
  473. }
  474. /**
  475. * 删除对象,如果是Undeleteable的entity,设置对象的状态而不是直接删除.
  476. *
  477. * @see HibernateEntityDao#remove(Object)
  478. */
  479. @Override
  480. public void remove(Object entity) {
  481. if (entityInfo.isUndeletable) {
  482. try {
  483. PropertyUtils.setProperty(entity, entityInfo.statusProperty, UNVALID_VALUE);
  484. save(entity);
  485. } catch (Exception e) {
  486. ReflectionUtils.handleReflectionException(e);
  487. }
  488. } else
  489. super.remove(entity);
  490. }
  491. /**
  492. * 与数据库相关的校验,比如判断名字在数据库里有没有重复, 在保存时被调用,在子类重载.
  493. *
  494. * @see #save(Object)
  495. */
  496. public void onValid(T entity) {
  497. }
  498. /**
  499. * 根据Map中的条件的Criteria查询.
  500. *
  501. * @param map Map中仅包含条件名与条件值,默认全部相同,可重载。
  502. */
  503. public List<T> find(Map map) {
  504. Criteria criteria = createCriteria();
  505. return find(criteria, map);
  506. }
  507. /**
  508. * 根据Map中的条件的Criteria查询.
  509. *
  510. * @param map Map中仅包含条件名与条件值,默认全部相同,可重载.
  511. */
  512. public List<T> find(Criteria criteria, Map map) {
  513. Assert.notNull(criteria);
  514. criteria.add(Restrictions.allEq(map));
  515. return criteria.list();
  516. }
  517. }
  518.  
  519. EntityInfo.java
  520. package com.demonstration.hibernate.dao.extend;
  521. /**
  522. * 装载Entity信息的内部类.
  523. *
  524. * @author springside
  525. *
  526. */
  527. class EntityInfo {
  528. boolean isUndeletable = false; // entity是否undeleteable的标志
  529. String statusProperty; // 标识状态的属性名
  530. @SuppressWarnings("unchecked")
  531. public EntityInfo(Class entityClass) {
  532. init(entityClass);
  533. }
  534. /**
  535. * 初始函数,判断EntityClass是否UndeletableEntity.
  536. */
  537. @SuppressWarnings("unchecked")
  538. private void init(Class entityClass) {
  539. // 通过EntityClass的interface判断entity是否undeletable
  540. if (IUndeletableEntity.class.isAssignableFrom(entityClass)) {
  541. isUndeletable = true;
  542. statusProperty = IUndeleteableEntityOperation.STATUS;
  543. }
  544. // 通过EntityClass的annotation判断entity是否undeletable
  545. if (entityClass.isAnnotationPresent(IUndeletable.class)) {
  546. isUndeletable = true;
  547. IUndeletable anno = (IUndeletable) entityClass.getAnnotation(IUndeletable.class);
  548. statusProperty = anno.status();
  549. }
  550. }
  551. }
  552.  
  553. IEntityDao.java
  554. package com.demonstration.hibernate.dao;
  555. import java.io.Serializable;
  556. import java.util.List;
  557. /**
  558. * 针对单个Entity对象的操作定义.不依赖于具体ORM实现方案.
  559. *
  560. * @author springside
  561. *
  562. */
  563. public interface IEntityDao<T> {
  564. T get(Serializable id);
  565. List<T> getAll();
  566. void save(Object o);
  567. void remove(Object o);
  568. void removeById(Serializable id);
  569. /**
  570. * 获取Entity对象的主键名.
  571. */
  572. @SuppressWarnings("unchecked")
  573. String getIdName(Class clazz);
  574. }
  575.  
  576. HibernateGenericDao.java
  577. package com.demonstration.hibernate.dao;
  578. import java.io.Serializable;
  579. import java.lang.reflect.InvocationTargetException;
  580. import java.util.ArrayList;
  581. import java.util.List;
  582. import java.util.regex.Matcher;
  583. import java.util.regex.Pattern;
  584. import org.apache.commons.beanutils.PropertyUtils;
  585. import org.hibernate.Criteria;
  586. import org.hibernate.Query;
  587. import org.hibernate.criterion.CriteriaSpecification;
  588. import org.hibernate.criterion.Criterion;
  589. import org.hibernate.criterion.DetachedCriteria;
  590. import org.hibernate.criterion.Order;
  591. import org.hibernate.criterion.Projection;
  592. import org.hibernate.criterion.Projections;
  593. import org.hibernate.criterion.Restrictions;
  594. import org.hibernate.impl.CriteriaImpl;
  595. import org.hibernate.metadata.ClassMetadata;
  596. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
  597. import org.springframework.util.Assert;
  598. import org.springframework.util.ReflectionUtils;
  599. import com.demonstration.hibernate.dao.support.BeanUtils;
  600. import com.demonstration.hibernate.dao.support.Page;
  601.  
  602. /**
  603. * Hibernate Dao的泛型基类.
  604. * <p/>
  605. * 继承于Spring的<code>HibernateDaoSupport</code>,提供分页函数和若干便捷查询方法,并对返回值作了泛型类型转换.
  606. *
  607. * @author springside
  608. *
  609. * @see HibernateDaoSupport
  610. * @see HibernateEntityDao
  611. */
  612. @SuppressWarnings("unchecked")
  613. public class HibernateGenericDao extends HibernateDaoSupport {
  614. /**
  615. * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
  616. */
  617. public <T> T get(Class<T> entityClass, Serializable id) {
  618. return (T) getHibernateTemplate().load(entityClass, id);
  619. }
  620. /**
  621. * 获取全部对象.
  622. */
  623. public <T> List<T> getAll(Class<T> entityClass) {
  624. return getHibernateTemplate().loadAll(entityClass);
  625. }
  626. /**
  627. * 获取全部对象,带排序字段与升降序参数.
  628. */
  629. public <T> List<T> getAll(Class<T> entityClass, String orderBy, boolean isAsc) {
  630. Assert.hasText(orderBy);
  631. if (isAsc)
  632. return getHibernateTemplate().findByCriteria(
  633. DetachedCriteria.forClass(entityClass).addOrder(Order.asc(orderBy)));
  634. else
  635. return getHibernateTemplate().findByCriteria(
  636. DetachedCriteria.forClass(entityClass).addOrder(Order.desc(orderBy)));
  637. }
  638. /**
  639. * 保存对象.
  640. */
  641. public void save(Object o) {
  642. getHibernateTemplate().saveOrUpdate(o);
  643. }
  644. /**
  645. * 删除对象.
  646. */
  647. public void remove(Object o) {
  648. getHibernateTemplate().delete(o);
  649. }
  650. /**
  651. * 根据ID删除对象.
  652. */
  653. public <T> void removeById(Class<T> entityClass, Serializable id) {
  654. remove(get(entityClass, id));
  655. }
  656. public void flush() {
  657. getHibernateTemplate().flush();
  658. }
  659. public void clear() {
  660. getHibernateTemplate().clear();
  661. }
  662. /**
  663. * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
  664. * 留意可以连续设置,如下:
  665. * <pre>
  666. * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
  667. * </pre>
  668. * 调用方式如下:
  669. * <pre>
  670. * dao.createQuery(hql)
  671. * dao.createQuery(hql,arg0);
  672. * dao.createQuery(hql,arg0,arg1);
  673. * dao.createQuery(hql,new Object[arg0,arg1,arg2])
  674. * </pre>
  675. *
  676. * @param values 可变参数.
  677. */
  678. public Query createQuery(String hql, Object... values) {
  679. Assert.hasText(hql);
  680. Query query = getSession().createQuery(hql);
  681. for (int i = 0; i < values.length; i++) {
  682. query.setParameter(i, values[i]);
  683. }
  684. return query;
  685. }
  686. /**
  687. * 创建Criteria对象.
  688. *
  689. * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)}
  690. */
  691. public <T> Criteria createCriteria(Class<T> entityClass, Criterion... criterions) {
  692. Criteria criteria = getSession().createCriteria(entityClass);
  693. for (Criterion c : criterions) {
  694. criteria.add(c);
  695. }
  696. return criteria;
  697. }
  698. /**
  699. * 创建Criteria对象,带排序字段与升降序字段.
  700. *
  701. * @see #createCriteria(Class,Criterion[])
  702. */
  703. public <T> Criteria createCriteria(Class<T> entityClass, String orderBy, boolean isAsc, Criterion... criterions) {
  704. Assert.hasText(orderBy);
  705. Criteria criteria = createCriteria(entityClass, criterions);
  706. if (isAsc)
  707. criteria.addOrder(Order.asc(orderBy));
  708. else
  709. criteria.addOrder(Order.desc(orderBy));
  710. return criteria;
  711. }
  712. /**
  713. * 根据hql查询,直接使用HibernateTemplate的find函数.
  714. *
  715. * @param values 可变参数,见{@link #createQuery(String,Object...)}
  716. */
  717. public List find(String hql, Object... values) {
  718. Assert.hasText(hql);
  719. return getHibernateTemplate().find(hql, values);
  720. }
  721. /**
  722. * 根据属性名和属性值查询对象.
  723. *
  724. * @return 符合条件的对象列表
  725. */
  726. public <T> List<T> findBy(Class<T> entityClass, String propertyName, Object value) {
  727. Assert.hasText(propertyName);
  728. return createCriteria(entityClass, Restrictions.eq(propertyName, value)).list();
  729. }
  730. /**
  731. * 根据属性名和属性值查询对象,带排序参数.
  732. */
  733. public <T> List<T> findBy(Class<T> entityClass, String propertyName, Object value, String orderBy, boolean isAsc) {
  734. Assert.hasText(propertyName);
  735. Assert.hasText(orderBy);
  736. return createCriteria(entityClass, orderBy, isAsc, Restrictions.eq(propertyName, value)).list();
  737. }
  738. /**
  739. * 根据属性名和属性值查询唯一对象.
  740. *
  741. * @return 符合条件的唯一对象 or null if not found.
  742. */
  743. public <T> T findUniqueBy(Class<T> entityClass, String propertyName, Object value) {
  744. Assert.hasText(propertyName);
  745. return (T) createCriteria(entityClass, Restrictions.eq(propertyName, value)).uniqueResult();
  746. }
  747. /**
  748. * 分页查询函数,使用hql.
  749. *
  750. * @param pageNo 页号,从1开始.
  751. */
  752. public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values) {
  753. Assert.hasText(hql);
  754. Assert.isTrue(pageNo >= 1, "pageNo should start from 1");
  755. // Count查询
  756. String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
  757. List countlist = getHibernateTemplate().find(countQueryString, values);
  758. long totalCount = (Long) countlist.get(0);
  759. if (totalCount < 1)
  760. return new Page();
  761. // 实际查询返回分页对象
  762. int startIndex = Page.getStartOfPage(pageNo, pageSize);
  763. Query query = createQuery(hql, values);
  764. List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
  765. return new Page(startIndex, totalCount, pageSize, list);
  766. }
  767.  
  768. /**
  769. * @author Scott.wanglei
  770. * @since 2008-7-21
  771. * @param hql 查询sql
  772. * @param start 分页从哪一条数据开始
  773. * @param pageSize 每一个页面的大小
  774. * @param values 查询条件
  775. * @return page对象
  776. */
  777. public Page dataQuery(String hql, int start, int pageSize, Object... values){
  778. // Count查询
  779. String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
  780. List countlist = getHibernateTemplate().find(countQueryString, values);
  781. long totalCount = (Long) countlist.get(0);
  782. if (totalCount < 1)
  783. return new Page();
  784. // 实际查询返回分页对象
  785. int startIndex = start;
  786. Query query = createQuery(hql, values);
  787. List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
  788. return new Page(startIndex, totalCount, pageSize, list);
  789. }
  790. /**
  791. * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
  792. *
  793. * @param pageNo 页号,从1开始.
  794. * @return 含总记录数和当前页数据的Page对象.
  795. */
  796. public Page pagedQuery(Criteria criteria, int pageNo, int pageSize) {
  797. Assert.notNull(criteria);
  798. Assert.isTrue(pageNo >= 1, "pageNo should start from 1");
  799. CriteriaImpl impl = (CriteriaImpl) criteria;
  800. // 先把Projection和OrderBy条件取出来,清空两者来执行Count操作
  801. Projection projection = impl.getProjection();
  802. List<CriteriaImpl.OrderEntry> orderEntries;
  803. try {
  804. orderEntries = (List) BeanUtils.forceGetProperty(impl, "orderEntries");
  805. BeanUtils.forceSetProperty(impl, "orderEntries", new ArrayList());
  806. } catch (Exception e) {
  807. throw new InternalError(" Runtime Exception impossibility throw ");
  808. }
  809. // 执行查询
  810. int totalCount = (Integer) criteria.setProjection(Projections.rowCount()).uniqueResult();
  811. // 将之前的Projection和OrderBy条件重新设回去
  812. criteria.setProjection(projection);
  813. if (projection == null) {
  814. criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
  815. }
  816. try {
  817. BeanUtils.forceSetProperty(impl, "orderEntries", orderEntries);
  818. } catch (Exception e) {
  819. throw new InternalError(" Runtime Exception impossibility throw ");
  820. }
  821. // 返回分页对象
  822. if (totalCount < 1)
  823. return new Page();
  824. int startIndex = Page.getStartOfPage(pageNo, pageSize);;
  825. List list = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();
  826. return new Page(startIndex, totalCount, pageSize, list);
  827. }
  828. /**
  829. * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
  830. *
  831. * @param pageNo 页号,从1开始.
  832. * @return 含总记录数和当前页数据的Page对象.
  833. */
  834. public Page pagedQuery(Class entityClass, int pageNo, int pageSize, Criterion... criterions) {
  835. Criteria criteria = createCriteria(entityClass, criterions);
  836. return pagedQuery(criteria, pageNo, pageSize);
  837. }
  838. /**
  839. * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
  840. *
  841. * @param pageNo 页号,从1开始.
  842. * @return 含总记录数和当前页数据的Page对象.
  843. */
  844. public Page pagedQuery(Class entityClass, int pageNo, int pageSize, String orderBy, boolean isAsc,
  845. Criterion... criterions) {
  846. Criteria criteria = createCriteria(entityClass, orderBy, isAsc, criterions);
  847. return pagedQuery(criteria, pageNo, pageSize);
  848. }
  849. /**
  850. * 判断对象某些属性的值在数据库中是否唯一.
  851. *
  852. * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  853. */
  854. public <T> boolean isUnique(Class<T> entityClass, Object entity, String uniquePropertyNames) {
  855. Assert.hasText(uniquePropertyNames);
  856. Criteria criteria = createCriteria(entityClass).setProjection(Projections.rowCount());
  857. String[] nameList = uniquePropertyNames.split(",");
  858. try {
  859. // 循环加入唯一列
  860. for (String name : nameList) {
  861. criteria.add(Restrictions.eq(name, PropertyUtils.getProperty(entity, name)));
  862. }
  863. // 以下代码为了如果是update的情况,排除entity自身.
  864. String idName = getIdName(entityClass);
  865. // 取得entity的主键值
  866. Serializable id = getId(entityClass, entity);
  867. // 如果id!=null,说明对象已存在,该操作为update,加入排除自身的判断
  868. if (id != null)
  869. criteria.add(Restrictions.not(Restrictions.eq(idName, id)));
  870. } catch (Exception e) {
  871. ReflectionUtils.handleReflectionException(e);
  872. }
  873. return (Integer) criteria.uniqueResult() == 0;
  874. }
  875. /**
  876. * 取得对象的主键值,辅助函数.
  877. */
  878. public Serializable getId(Class entityClass, Object entity) throws NoSuchMethodException, IllegalAccessException,
  879. InvocationTargetException {
  880. Assert.notNull(entity);
  881. Assert.notNull(entityClass);
  882. return (Serializable) PropertyUtils.getProperty(entity, getIdName(entityClass));
  883. }
  884. /**
  885. * 取得对象的主键名,辅助函数.
  886. */
  887. public String getIdName(Class clazz) {
  888. Assert.notNull(clazz);
  889. ClassMetadata meta = getSessionFactory().getClassMetadata(clazz);
  890. Assert.notNull(meta, "Class " + clazz + " not define in hibernate session factory.");
  891. String idName = meta.getIdentifierPropertyName();
  892. Assert.hasText(idName, clazz.getSimpleName() + " has no identifier property define.");
  893. return idName;
  894. }
  895. /**
  896. * 去除hql的select 子句,未考虑union的情况,用于pagedQuery.
  897. *
  898. * @see #pagedQuery(String,int,int,Object[])
  899. */
  900. private static String removeSelect(String hql) {
  901. Assert.hasText(hql);
  902. int beginPos = hql.toLowerCase().indexOf("from");
  903. Assert.isTrue(beginPos != -1, " hql : " + hql + " must has a keyword 'from'");
  904. return hql.substring(beginPos);
  905. }
  906. /**
  907. * 去除hql的orderby 子句,用于pagedQuery.
  908. *
  909. * @see #pagedQuery(String,int,int,Object[])
  910. */
  911. private static String removeOrders(String hql) {
  912. Assert.hasText(hql);
  913. Pattern p = Pattern.compile("order//s*by[//w|//W|//s|//S]*", Pattern.CASE_INSENSITIVE);
  914. Matcher m = p.matcher(hql);
  915. StringBuffer sb = new StringBuffer();
  916. while (m.find()) {
  917. m.appendReplacement(sb, "");
  918. }
  919. m.appendTail(sb);
  920. return sb.toString();
  921. }
  922.  
  923. }
  924. HibernateEntityDao.java
  925. package com.demonstration.hibernate.dao;
  926. import java.io.Serializable;
  927. import java.util.List;
  928. import org.hibernate.Criteria;
  929. import org.hibernate.criterion.Criterion;
  930. import com.demonstration.hibernate.dao.support.GenericsUtils;
  931. /**
  932. * 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类. <p/> 子类只要在类定义时指定所管理Entity的Class,
  933. * 即拥有对单个Entity对象的CRUD操作.
  934. *
  935. * <pre>
  936. * public class UserManager extends HibernateEntityDao<User> {
  937. * }
  938. * </pre>
  939. *
  940. * @author springside
  941. *
  942. * @see HibernateGenericDao
  943. */
  944. @SuppressWarnings("unchecked")
  945. public class HibernateEntityDao<T> extends HibernateGenericDao implements
  946. IEntityDao<T> {
  947. protected Class<T> entityClass;// DAO所管理的Entity类型.
  948. /**
  949. * 在构造函数中将泛型T.class赋给entityClass.
  950. */
  951. public HibernateEntityDao() {
  952. entityClass = GenericsUtils.getSuperClassGenricType(getClass());
  953. }
  954. /**
  955. * 重载构造函数 让spring提供构造函数注入
  956. */
  957. public HibernateEntityDao(Class<T> type) {
  958. this.entityClass = type;
  959. }
  960.  
  961. /**
  962. * 取得entityClass.JDK1.4不支持泛型的子类可以抛开Class<T> entityClass,重载此函数达到相同效果。
  963. */
  964. protected Class<T> getEntityClass() {
  965. return entityClass;
  966. }
  967.  
  968. public void setEntityClass(Class<T> type){
  969. this.entityClass=type;
  970. }
  971. /**
  972. * 根据ID获取对象.
  973. *
  974. * @see HibernateGenericDao#getId(Class,Object)
  975. */
  976. public T get(Serializable id) {
  977. return get(getEntityClass(), id);
  978. }
  979. /**
  980. * 获取全部对象
  981. *
  982. * @see HibernateGenericDao#getAll(Class)
  983. */
  984. public List<T> getAll() {
  985. return getAll(getEntityClass());
  986. }
  987. /**
  988. * 获取全部对象,带排序参数.
  989. *
  990. * @see HibernateGenericDao#getAll(Class,String,boolean)
  991. */
  992. public List<T> getAll(String orderBy, boolean isAsc) {
  993. return getAll(getEntityClass(), orderBy, isAsc);
  994. }
  995. /**
  996. * 根据ID移除对象.
  997. *
  998. * @see HibernateGenericDao#removeById(Class,Serializable)
  999. */
  1000. public void removeById(Serializable id) {
  1001. removeById(getEntityClass(), id);
  1002. }
  1003. /**
  1004. * 取得Entity的Criteria.
  1005. *
  1006. * @see HibernateGenericDao#createCriteria(Class,Criterion[])
  1007. */
  1008. public Criteria createCriteria(Criterion... criterions) {
  1009. return createCriteria(getEntityClass(), criterions);
  1010. }
  1011. /**
  1012. * 取得Entity的Criteria,带排序参数.
  1013. *
  1014. * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[])
  1015. */
  1016. public Criteria createCriteria(String orderBy, boolean isAsc,
  1017. Criterion... criterions) {
  1018. return createCriteria(getEntityClass(), orderBy, isAsc, criterions);
  1019. }
  1020. /**
  1021. * 根据属性名和属性值查询对象.
  1022. *
  1023. * @return 符合条件的对象列表
  1024. * @see HibernateGenericDao#findBy(Class,String,Object)
  1025. */
  1026. public List<T> findBy(String propertyName, Object value) {
  1027. return findBy(getEntityClass(), propertyName, value);
  1028. }
  1029. /**
  1030. * 根据属性名和属性值查询对象,带排序参数.
  1031. *
  1032. * @return 符合条件的对象列表
  1033. * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean)
  1034. */
  1035. public List<T> findBy(String propertyName, Object value, String orderBy,
  1036. boolean isAsc) {
  1037. return findBy(getEntityClass(), propertyName, value, orderBy, isAsc);
  1038. }
  1039. /**
  1040. * 根据属性名和属性值查询单个对象.
  1041. *
  1042. * @return 符合条件的唯一对象 or null
  1043. * @see HibernateGenericDao#findUniqueBy(Class,String,Object)
  1044. */
  1045. public T findUniqueBy(String propertyName, Object value) {
  1046. return findUniqueBy(getEntityClass(), propertyName, value);
  1047. }
  1048. /**
  1049. * 判断对象某些属性的值在数据库中唯一.
  1050. *
  1051. * @param uniquePropertyNames
  1052. * 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  1053. * @see HibernateGenericDao#isUnique(Class,Object,String)
  1054. */
  1055. public boolean isUnique(Object entity, String uniquePropertyNames) {
  1056. return isUnique(getEntityClass(), entity, uniquePropertyNames);
  1057. }
  1058. /**
  1059. * 消除与 Hibernate Session 的关联
  1060. *
  1061. * @param entity
  1062. */
  1063. public void evit(Object entity) {
  1064. getHibernateTemplate().evict(entity);
  1065. }
  1066. }
  1067.  
  1068. IBaseDao.java
  1069. /**
  1070. *
  1071. */
  1072. package com.demonstration.hibernate.basedao;
  1073. import java.io.Serializable;
  1074. import java.lang.reflect.InvocationTargetException;
  1075. import java.util.List;
  1076. import java.util.Map;
  1077. import org.hibernate.Criteria;
  1078. import org.hibernate.Query;
  1079. import org.hibernate.criterion.Criterion;
  1080. import com.demonstration.hibernate.dao.HibernateEntityDao;
  1081. import com.demonstration.hibernate.dao.HibernateGenericDao;
  1082. import com.demonstration.hibernate.dao.extend.IUndeleteableEntityOperation;
  1083. import com.demonstration.hibernate.dao.support.Page;
  1084.  
  1085. /**
  1086. * @author
  1087. *
  1088. * 提供hibernate dao的所有操作,
  1089. * 实现类由spring注入HibernateEntityDao和HibernateEntityExtendDao来实现
  1090. * 最大限度的解耦hibernate持久层的操作
  1091. */
  1092. public interface IBaseDao<T> {
  1093. /**
  1094. * 根据ID获取对象.
  1095. *
  1096. * @see HibernateGenericDao#getId(Class,Object)
  1097. */
  1098. public T get(Serializable id);
  1099.  
  1100. /**
  1101. * 获取全部对象
  1102. *
  1103. * @see HibernateGenericDao#getAll(Class)
  1104. */
  1105. public List<T> getAll();
  1106.  
  1107. /**
  1108. * 获取全部对象,带排序参数.
  1109. *
  1110. * @see HibernateGenericDao#getAll(Class,String,boolean)
  1111. */
  1112. public List<T> getAll(String orderBy, boolean isAsc);
  1113.  
  1114. /**
  1115. * 根据ID移除对象.
  1116. *
  1117. * @see HibernateGenericDao#removeById(Class,Serializable)
  1118. */
  1119. public void removeById(Serializable id);
  1120.  
  1121. /**
  1122. * 取得Entity的Criteria.
  1123. *
  1124. * @see HibernateGenericDao#createCriteria(Class,Criterion[])
  1125. */
  1126. public Criteria createCriteria(Criterion... criterions);
  1127.  
  1128. /**
  1129. * 取得Entity的Criteria,带排序参数.
  1130. *
  1131. * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[])
  1132. */
  1133. public Criteria createCriteria(String orderBy, boolean isAsc,
  1134. Criterion... criterions);
  1135.  
  1136. /**
  1137. * 根据属性名和属性值查询对象.
  1138. *
  1139. * @return 符合条件的对象列表
  1140. * @see HibernateGenericDao#findBy(Class,String,Object)
  1141. */
  1142. public List<T> findBy(String propertyName, Object value);
  1143.  
  1144. /**
  1145. * 根据属性名和属性值查询对象,带排序参数.
  1146. *
  1147. * @return 符合条件的对象列表
  1148. * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean)
  1149. */
  1150. public List<T> findBy(String propertyName, Object value, String orderBy,
  1151. boolean isAsc);
  1152.  
  1153. /**
  1154. * 根据属性名和属性值查询单个对象.
  1155. *
  1156. * @return 符合条件的唯一对象 or null
  1157. * @see HibernateGenericDao#findUniqueBy(Class,String,Object)
  1158. */
  1159. public T findUniqueBy(String propertyName, Object value);
  1160.  
  1161. /**
  1162. * 判断对象某些属性的值在数据库中唯一.
  1163. *
  1164. * @param uniquePropertyNames
  1165. * 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  1166. * @see HibernateGenericDao#isUnique(Class,Object,String)
  1167. */
  1168. public boolean isUnique(Object entity, String uniquePropertyNames);
  1169.  
  1170. /**
  1171. * 消除与 Hibernate Session 的关联
  1172. *
  1173. * @param entity
  1174. */
  1175. public void evit(Object entity);
  1176.  
  1177. /*******************************************************************************************/
  1178.  
  1179. /**
  1180. * 取得所有状态为有效的对象.
  1181. *
  1182. * @see IUndeleteableEntityOperation#getAllValid()
  1183. */
  1184. public List<T> getAllValid();
  1185.  
  1186. /**
  1187. * 获取过滤已删除对象的hql条件语句.
  1188. *
  1189. * @see IUndeleteableEntityOperation#getUnDeletableHQL()
  1190. */
  1191. public String getUnDeletableHQL();
  1192.  
  1193. /**
  1194. * 获取过滤已删除对象的Criterion条件语句.
  1195. *
  1196. * @see UndeleteableEntityOperation#
  1197. */
  1198. public Criterion getUnDeletableCriterion();
  1199.  
  1200. /**
  1201. * 重载保存函数,在保存前先调用onValid(T),进行书名不重复等数据库相关的校验.
  1202. *
  1203. * @see #onValid(Object)
  1204. * @see HibernateEntityDao#save(Object)
  1205. */
  1206. public void saveOnValid(Object entity);
  1207.  
  1208. /**
  1209. * 删除对象,如果是Undeleteable的entity,设置对象的状态而不是直接删除.
  1210. *
  1211. * @see HibernateEntityDao#remove(Object)
  1212. */
  1213. public void removeUndeleteable(Object entity);
  1214.  
  1215. /**
  1216. * 与数据库相关的校验,比如判断名字在数据库里有没有重复, 在保存时被调用,在子类重载.
  1217. *
  1218. * @see #save(Object)
  1219. */
  1220. public void onValid(T entity);
  1221.  
  1222. /**
  1223. * 根据Map中的条件的Criteria查询.
  1224. *
  1225. * @param map Map中仅包含条件名与条件值,默认全部相同,可重载。
  1226. */
  1227. @SuppressWarnings("unchecked")
  1228. public List<T> find(Map map);
  1229.  
  1230. /**
  1231. * 根据Map中的条件的Criteria查询.
  1232. *
  1233. * @param map Map中仅包含条件名与条件值,默认全部相同,可重载.
  1234. */
  1235. @SuppressWarnings("unchecked")
  1236. public List<T> find(Criteria criteria, Map map);
  1237.  
  1238. /*******************************************************************************************/
  1239.  
  1240. /**
  1241. * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
  1242. */
  1243. public T get(Class<T> entityClass, Serializable id);
  1244.  
  1245. /**
  1246. * 获取全部对象.
  1247. */
  1248. public List<T> getAll(Class<T> entityClass);
  1249.  
  1250. /**
  1251. * 获取全部对象,带排序字段与升降序参数.
  1252. */
  1253. public List<T> getAll(Class<T> entityClass, String orderBy, boolean isAsc);
  1254.  
  1255. /**
  1256. * 保存对象.
  1257. */
  1258. public void save(Object o);
  1259.  
  1260. /**
  1261. * 删除对象.
  1262. */
  1263. public void remove(Object o);
  1264.  
  1265. public void flush();
  1266.  
  1267. public void clear();
  1268.  
  1269. /**
  1270. * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
  1271. * 留意可以连续设置,如下:
  1272. * <pre>
  1273. * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
  1274. * </pre>
  1275. * 调用方式如下:
  1276. * <pre>
  1277. * dao.createQuery(hql)
  1278. * dao.createQuery(hql,arg0);
  1279. * dao.createQuery(hql,arg0,arg1);
  1280. * dao.createQuery(hql,new Object[arg0,arg1,arg2])
  1281. * </pre>
  1282. *
  1283. * @param values 可变参数.
  1284. */
  1285. public Query createQuery(String hql, Object... values);
  1286.  
  1287. /**
  1288. * 创建Criteria对象.
  1289. *
  1290. * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)}
  1291. */
  1292. public Criteria createCriteria(Class<T> entityClass, Criterion... criterions);
  1293.  
  1294. /**
  1295. * 创建Criteria对象,带排序字段与升降序字段.
  1296. *
  1297. * @see #createCriteria(Class,Criterion[])
  1298. */
  1299. public Criteria createCriteria(Class<T> entityClass, String orderBy, boolean isAsc, Criterion... criterions);
  1300.  
  1301. /**
  1302. * 根据hql查询,直接使用HibernateTemplate的find函数.
  1303. *
  1304. * @param values 可变参数,见{@link #createQuery(String,Object...)}
  1305. */
  1306. @SuppressWarnings("unchecked")
  1307. public List find(String hql, Object... values);
  1308.  
  1309. /**
  1310. * 根据属性名和属性值查询对象.
  1311. *
  1312. * @return 符合条件的对象列表
  1313. */
  1314. public List<T> findBy(Class<T> entityClass, String propertyName, Object value);
  1315.  
  1316. /**
  1317. * 根据属性名和属性值查询对象,带排序参数.
  1318. */
  1319. public List<T> findBy(Class<T> entityClass, String propertyName, Object value, String orderBy, boolean isAsc);
  1320.  
  1321. /**
  1322. * 根据属性名和属性值查询唯一对象.
  1323. *
  1324. * @return 符合条件的唯一对象 or null if not found.
  1325. */
  1326. public T findUniqueBy(Class<T> entityClass, String propertyName, Object value);
  1327.  
  1328. /**
  1329. * 分页查询函数,使用hql.
  1330. *
  1331. * @param pageNo 页号,从1开始.
  1332. */
  1333. public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values);
  1334.  
  1335. /**
  1336. * @author Scott.wanglei
  1337. * @since 2008-7-21
  1338. * @param hql 查询sql
  1339. * @param start 分页从哪一条数据开始
  1340. * @param pageSize 每一个页面的大小
  1341. * @param values 查询条件
  1342. * @return page对象
  1343. */
  1344. public Page dataQuery(String hql, int start, int pageSize, Object... values);
  1345.  
  1346. /**
  1347. * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
  1348. *
  1349. * @param pageNo 页号,从1开始.
  1350. * @return 含总记录数和当前页数据的Page对象.
  1351. */
  1352. public Page pagedQuery(Criteria criteria, int pageNo, int pageSize);
  1353.  
  1354. /**
  1355. * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
  1356. *
  1357. * @param pageNo 页号,从1开始.
  1358. * @return 含总记录数和当前页数据的Page对象.
  1359. */
  1360. @SuppressWarnings("unchecked")
  1361. public Page pagedQuery(Class entityClass, int pageNo, int pageSize, Criterion... criterions);
  1362.  
  1363. /**
  1364. * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
  1365. *
  1366. * @param pageNo 页号,从1开始.
  1367. * @return 含总记录数和当前页数据的Page对象.
  1368. */
  1369. @SuppressWarnings("unchecked")
  1370. public Page pagedQuery(Class entityClass, int pageNo, int pageSize, String orderBy, boolean isAsc,
  1371. Criterion... criterions);
  1372.  
  1373. /**
  1374. * 判断对象某些属性的值在数据库中是否唯一.
  1375. *
  1376. * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  1377. */
  1378. public boolean isUnique(Class<T> entityClass, Object entity, String uniquePropertyNames);
  1379.  
  1380. /**
  1381. * 取得对象的主键值,辅助函数.
  1382. */
  1383. @SuppressWarnings("unchecked")
  1384. public Serializable getId(Class entityClass, Object entity) throws NoSuchMethodException, IllegalAccessException,
  1385. InvocationTargetException ;
  1386.  
  1387. /**
  1388. * 取得对象的主键名,辅助函数.
  1389. */
  1390. @SuppressWarnings("unchecked")
  1391. public String getIdName(Class clazz);
  1392. }
  1393.  
  1394. BaseDao.java
  1395. /**
  1396. *
  1397. */
  1398. package com.demonstration.hibernate.basedao;
  1399. import java.io.Serializable;
  1400. import java.lang.reflect.InvocationTargetException;
  1401. import java.util.List;
  1402. import java.util.Map;
  1403. import org.hibernate.Criteria;
  1404. import org.hibernate.Query;
  1405. import org.hibernate.criterion.Criterion;
  1406. import com.demonstration.hibernate.dao.HibernateEntityDao;
  1407. import com.demonstration.hibernate.dao.HibernateGenericDao;
  1408. import com.demonstration.hibernate.dao.extend.HibernateEntityExtendDao;
  1409. import com.demonstration.hibernate.dao.extend.IUndeleteableEntityOperation;
  1410. import com.demonstration.hibernate.dao.support.Page;
  1411.  
  1412. /**
  1413. * @author
  1414. *
  1415. * IBaseDao的实现类通过spring注入HibernateEntityDao和HibernateEntityExtendDao来实现
  1416. */
  1417. public class BaseDao<T> implements IBaseDao<T> {
  1418. protected Class<T> entityClass;// DAO所管理的Entity类型.
  1419. private HibernateEntityDao<T> hedao;
  1420. private HibernateEntityExtendDao<T> hexdao;
  1421.  
  1422. public void setHedao(HibernateEntityDao<T> hedao) {
  1423. hedao.setEntityClass(entityClass);
  1424. this.hedao=hedao;
  1425. }
  1426. public void setHexdao(HibernateEntityExtendDao<T> hexdao) {
  1427. hexdao.setEntityClass(entityClass);
  1428. this.hexdao=hexdao;
  1429. }
  1430.  
  1431. /**
  1432. *让spring提供构造函数注入
  1433. */
  1434. public BaseDao(Class<T> type) {
  1435. this.entityClass = type;
  1436. }
  1437.  
  1438. public BaseDao(){}
  1439. /**
  1440. * 根据ID获取对象.
  1441. *
  1442. * @see HibernateGenericDao#getId(Class,Object)
  1443. */
  1444. public T get(Serializable id) {
  1445. return hedao.get(id);
  1446. }
  1447. /**
  1448. * 获取全部对象
  1449. *
  1450. * @see HibernateGenericDao#getAll(Class)
  1451. */
  1452. public List<T> getAll() {
  1453. return hedao.getAll();
  1454. }
  1455.  
  1456. /**
  1457. * 获取全部对象,带排序参数.
  1458. *
  1459. * @see HibernateGenericDao#getAll(Class,String,boolean)
  1460. */
  1461. public List<T> getAll(String orderBy, boolean isAsc) {
  1462. return hedao.getAll(orderBy, isAsc);
  1463. }
  1464. /**
  1465. * 根据ID移除对象.
  1466. *
  1467. * @see HibernateGenericDao#removeById(Class,Serializable)
  1468. */
  1469. public void removeById(Serializable id) {
  1470. hedao.removeById(id);
  1471. }
  1472. /**
  1473. * 取得Entity的Criteria.
  1474. *
  1475. * @see HibernateGenericDao#createCriteria(Class,Criterion[])
  1476. */
  1477. public Criteria createCriteria(Criterion... criterions) {
  1478. return hedao.createCriteria(criterions);
  1479. }
  1480. /**
  1481. * 取得Entity的Criteria,带排序参数.
  1482. *
  1483. * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[])
  1484. */
  1485. public Criteria createCriteria(String orderBy, boolean isAsc,
  1486. Criterion... criterions) {
  1487. return hedao.createCriteria(orderBy, isAsc, criterions);
  1488. }
  1489. /**
  1490. * 根据属性名和属性值查询对象.
  1491. *
  1492. * @return 符合条件的对象列表
  1493. * @see HibernateGenericDao#findBy(Class,String,Object)
  1494. */
  1495. public List<T> findBy(String propertyName, Object value) {
  1496. return hedao.findBy(propertyName, value);
  1497. }
  1498. /**
  1499. * 根据属性名和属性值查询对象,带排序参数.
  1500. *
  1501. * @return 符合条件的对象列表
  1502. * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean)
  1503. */
  1504. public List<T> findBy(String propertyName, Object value, String orderBy,
  1505. boolean isAsc) {
  1506. return hedao.findBy(propertyName, value, orderBy, isAsc);
  1507. }
  1508. /**
  1509. * 根据属性名和属性值查询单个对象.
  1510. *
  1511. * @return 符合条件的唯一对象 or null
  1512. * @see HibernateGenericDao#findUniqueBy(Class,String,Object)
  1513. */
  1514. public T findUniqueBy(String propertyName, Object value) {
  1515. return hedao.findUniqueBy(propertyName, value);
  1516. }
  1517. /**
  1518. * 判断对象某些属性的值在数据库中唯一.
  1519. *
  1520. * @param uniquePropertyNames
  1521. * 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  1522. * @see HibernateGenericDao#isUnique(Class,Object,String)
  1523. */
  1524. public boolean isUnique(Object entity, String uniquePropertyNames) {
  1525. return hedao.isUnique(entity, uniquePropertyNames);
  1526. }
  1527. /**
  1528. * 消除与 Hibernate Session 的关联
  1529. *
  1530. * @param entity
  1531. */
  1532. public void evit(Object entity) {
  1533. hedao.evit(entity);
  1534. }
  1535. /**
  1536. * 取得所有状态为有效的对象.
  1537. *
  1538. * @see IUndeleteableEntityOperation#getAllValid()
  1539. */
  1540. public List<T> getAllValid() {
  1541. return hexdao.getAllValid();
  1542. }
  1543. /**
  1544. * 获取过滤已删除对象的hql条件语句.
  1545. *
  1546. * @see IUndeleteableEntityOperation#getUnDeletableHQL()
  1547. */
  1548. public String getUnDeletableHQL() {
  1549. return hexdao.getUnDeletableHQL();
  1550. }
  1551. /**
  1552. * 获取过滤已删除对象的Criterion条件语句.
  1553. *
  1554. * @see UndeleteableEntityOperation#
  1555. */
  1556. public Criterion getUnDeletableCriterion() {
  1557. return hexdao.getUnDeletableCriterion();
  1558. }
  1559. /**
  1560. * 重载保存函数,在保存前先调用onValid(T),进行书名不重复等数据库相关的校验.
  1561. *
  1562. * @see #onValid(Object)
  1563. * @see HibernateEntityDao#save(Object)
  1564. */
  1565. public void saveOnValid(Object entity) {
  1566. hexdao.save(entity);
  1567. }
  1568. /**
  1569. * 删除对象,如果是Undeleteable的entity,设置对象的状态而不是直接删除.
  1570. *
  1571. * @see HibernateEntityDao#remove(Object)
  1572. */
  1573. public void removeUndeleteable(Object entity) {
  1574. hexdao.remove(entity);
  1575. }
  1576. /**
  1577. * 与数据库相关的校验,比如判断名字在数据库里有没有重复, 在保存时被调用,在此可重写.
  1578. *
  1579. * @see #save(Object)
  1580. */
  1581. public void onValid(T entity) {
  1582.  
  1583. }
  1584. /**
  1585. * 根据Map中的条件的Criteria查询.
  1586. *
  1587. * @param map Map中仅包含条件名与条件值,默认全部相同,可重载。
  1588. */
  1589. @SuppressWarnings("unchecked")
  1590. public List<T> find(Map map) {
  1591. return hexdao.find(map);
  1592. }
  1593. /**
  1594. * 根据Map中的条件的Criteria查询.
  1595. *
  1596. * @param map Map中仅包含条件名与条件值,默认全部相同,可重载.
  1597. */
  1598. @SuppressWarnings("unchecked")
  1599. public List<T> find(Criteria criteria, Map map) {
  1600. return hexdao.find(criteria, map);
  1601. }
  1602. /**
  1603. * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
  1604. */
  1605. public T get(Class<T> entityClass, Serializable id) {
  1606. return hedao.get(entityClass, id);
  1607. }
  1608. /**
  1609. * 获取全部对象.
  1610. */
  1611. public List<T> getAll(Class<T> entityClass) {
  1612. return hedao.getAll(entityClass);
  1613. }
  1614. /**
  1615. * 获取全部对象,带排序字段与升降序参数.
  1616. */
  1617. public List<T> getAll(Class<T> entityClass, String orderBy, boolean isAsc) {
  1618. return hedao.getAll(entityClass, orderBy, isAsc);
  1619. }
  1620. /**
  1621. * 保存对象.
  1622. */
  1623. public void save(Object o) {
  1624. hedao.save(o);
  1625. }
  1626. /**
  1627. * 删除对象.
  1628. */
  1629. public void remove(Object o) {
  1630. hedao.remove(o);
  1631. }
  1632.  
  1633. public void flush(){
  1634. hedao.flush();
  1635. }
  1636.  
  1637. public void clear(){
  1638. hedao.clear();
  1639. }
  1640. /**
  1641. * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
  1642. * 留意可以连续设置,如下:
  1643. * <pre>
  1644. * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
  1645. * </pre>
  1646. * 调用方式如下:
  1647. * <pre>
  1648. * dao.createQuery(hql)
  1649. * dao.createQuery(hql,arg0);
  1650. * dao.createQuery(hql,arg0,arg1);
  1651. * dao.createQuery(hql,new Object[arg0,arg1,arg2])
  1652. * </pre>
  1653. *
  1654. * @param values 可变参数.
  1655. */
  1656. public Query createQuery(String hql, Object... values) {
  1657.  
  1658. return hedao.createQuery(hql, values);
  1659. }
  1660. /**
  1661. * 创建Criteria对象.
  1662. *
  1663. * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)}
  1664. */
  1665. public Criteria createCriteria(Class<T> entityClass,
  1666. Criterion... criterions) {
  1667.  
  1668. return hedao.createCriteria(entityClass, criterions);
  1669. }
  1670. /**
  1671. * 创建Criteria对象,带排序字段与升降序字段.
  1672. *
  1673. * @see #createCriteria(Class,Criterion[])
  1674. */
  1675. public Criteria createCriteria(Class<T> entityClass, String orderBy,
  1676. boolean isAsc, Criterion... criterions) {
  1677. return hedao.createCriteria(entityClass, orderBy, isAsc, criterions);
  1678. }
  1679. /**
  1680. * 根据hql查询,直接使用HibernateTemplate的find函数.
  1681. *
  1682. * @param values 可变参数,见{@link #createQuery(String,Object...)}
  1683. */
  1684. @SuppressWarnings("unchecked")
  1685. public List find(String hql, Object... values) {
  1686. return hedao.find(hql, values);
  1687. }
  1688. /**
  1689. * 根据属性名和属性值查询对象.
  1690. *
  1691. * @return 符合条件的对象列表
  1692. */
  1693. public List<T> findBy(Class<T> entityClass, String propertyName,
  1694. Object value) {
  1695.  
  1696. return hedao.findBy(entityClass, propertyName, value);
  1697. }
  1698. /**
  1699. * 根据属性名和属性值查询对象,带排序参数.
  1700. */
  1701. public List<T> findBy(Class<T> entityClass, String propertyName,
  1702. Object value, String orderBy, boolean isAsc) {
  1703. return hedao.findBy(entityClass, propertyName, value, orderBy, isAsc);
  1704. }
  1705. /**
  1706. * 根据属性名和属性值查询唯一对象.
  1707. *
  1708. * @return 符合条件的唯一对象 or null if not found.
  1709. */
  1710. public T findUniqueBy(Class<T> entityClass, String propertyName,
  1711. Object value) {
  1712. return hedao.findUniqueBy(propertyName, value);
  1713. }
  1714. /**
  1715. * 分页查询函数,使用hql.
  1716. *
  1717. * @param pageNo 页号,从1开始.
  1718. */
  1719. public Page pagedQuery(String hql, int pageNo, int pageSize,
  1720. Object... values) {
  1721. return hedao.pagedQuery(hql, pageNo, pageSize, values);
  1722. }
  1723. /**
  1724. * @author Scott.wanglei
  1725. * @since 2008-7-21
  1726. * @param hql 查询sql
  1727. * @param start 分页从哪一条数据开始
  1728. * @param pageSize 每一个页面的大小
  1729. * @param values 查询条件
  1730. * @return page对象
  1731. */
  1732. public Page dataQuery(String hql, int start, int pageSize, Object... values) {
  1733. return hedao.dataQuery(hql, start, pageSize, values);
  1734. }
  1735. /**
  1736. * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
  1737. *
  1738. * @param pageNo 页号,从1开始.
  1739. * @return 含总记录数和当前页数据的Page对象.
  1740. */
  1741. public Page pagedQuery(Criteria criteria, int pageNo, int pageSize) {
  1742. return hedao.pagedQuery(criteria, pageNo, pageSize);
  1743. }
  1744.  
  1745. /**
  1746. * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
  1747. *
  1748. * @param pageNo 页号,从1开始.
  1749. * @return 含总记录数和当前页数据的Page对象.
  1750. */
  1751. @SuppressWarnings("unchecked")
  1752. public Page pagedQuery(Class entityClass, int pageNo, int pageSize,
  1753. Criterion... criterions) {
  1754. return hedao.pagedQuery(entityClass, pageNo, pageSize, criterions);
  1755. }
  1756. @SuppressWarnings("unchecked")
  1757. public Page pagedQuery(Class entityClass, int pageNo, int pageSize,
  1758. String orderBy, boolean isAsc, Criterion... criterions) {
  1759. return hedao.pagedQuery(entityClass, pageNo, pageSize, orderBy, isAsc, criterions);
  1760. }
  1761. /**
  1762. * 判断对象某些属性的值在数据库中是否唯一.
  1763. *
  1764. * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  1765. */
  1766. public boolean isUnique(Class<T> entityClass, Object entity,
  1767. String uniquePropertyNames) {
  1768. return hedao.isUnique(entity, uniquePropertyNames);
  1769. }
  1770. /**
  1771. * 取得对象的主键值,辅助函数.
  1772. */
  1773. @SuppressWarnings("unchecked")
  1774. public Serializable getId(Class entityClass, Object entity)
  1775. throws NoSuchMethodException, IllegalAccessException,
  1776. InvocationTargetException {
  1777. return hedao.getId(entityClass, entity);
  1778. }
  1779. /**
  1780. * 取得对象的主键名,辅助函数.
  1781. */
  1782. @SuppressWarnings("unchecked")
  1783. public String getIdName(Class clazz) {
  1784. return hedao.getIdName(clazz);
  1785. }
  1786. }
  1787.  
  1788. 使用时候的xml配置:
  1789. <?xml version="1.0" encoding="UTF-8"?>
  1790. <beans xmlns="http://www.springframework.org/schema/beans"
  1791. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  1792. xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
  1793. <bean id="hedao"
  1794. class="com.demonstration.hibernate.dao.HibernateEntityDao" scope="prototype">
  1795. <property name="sessionFactory">
  1796. <ref bean="sessionFactory" />
  1797. </property>
  1798. </bean>
  1799. <bean id="hexdao"
  1800. class="com.demonstration.hibernate.dao.extend.HibernateEntityExtendDao" scope="prototype">
  1801. <property name="sessionFactory">
  1802. <ref bean="sessionFactory" />
  1803. </property>
  1804. </bean>
  1805.  
  1806. <!--使用泛型DAO作为抽象基类-->
  1807. <bean id="baseDao" class="com.demonstration.hibernate.basedao.BaseDao"
  1808. abstract="true" depends-on="hedao,hexdao">
  1809. <property name="hedao">
  1810. <ref bean="hedao" />
  1811. </property>
  1812. <property name="hexdao">
  1813. <ref bean="hexdao" />
  1814. </property>
  1815. </bean>
  1816.  
  1817. <!--下面这个dao没有写任何java代码完全有spring搞定 -->
  1818. <!-- 配置实体类的DAO -->
  1819. <bean id="demoDao" parent="baseDao">
  1820. <constructor-arg>
  1821. <!--根据这个生成某一个实体的dao -->
  1822. <value>com.demonstration.entityclass.Demodata</value>
  1823. </constructor-arg>
  1824. </bean>
  1825. </beans>

一个好用的hibernate泛型dao的更多相关文章

  1. 《项目架构那点儿事》——Hibernate泛型Dao,让持久层简洁起来

    [前言]hibernate作为持久层ORM技术,它对JDBC进行非常轻量级对象封装,使得我们可以随心所欲的使用面向对象的思想来操作数据 库.同时,作为后台开发的支撑,的确扮演了一个举足轻重的角色,那么 ...

  2. Hibernate也须要呵护——Hibernate的泛型DAO

    众所周之.面向对象的基础是抽象.也能够说,抽象促使编程在不断发展. 对于数据库的訪问,以前写过HqlHelper.EFHelper.编写Spring+Hibernate框架下的应用.也相同离不了编写一 ...

  3. [Hibernate] - Generic Dao

    使用泛型写了一个通用的Hibernate DAO类. GenericDao接口 package com.my.dao; import java.io.Serializable; import java ...

  4. Hibernate的Dao层通用设计

    hibernate作为一款优秀的数据库持久化框架,在现实的运用中是非常广泛的.它的出现让不熟悉sql语法的程序员能开发数据库连接层成为一种可能,但是理想与现实永远是有差距的.开发过程中如果只使用hql ...

  5. 泛型DAO与泛型Service

    泛型Dao与Service 看了几个帖子,泛型Dao与Service的主要目的就是要减少重复代码.具体的说明如下: 1. 定义一个BaseDao接口,此接口包含了一些通用的DAO操作,例如:增加.删除 ...

  6. SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装

    SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装 >>>>>>>& ...

  7. 泛型DAO

    最近正在学习泛型DAO,通过网上查阅资料,汇总并自己整理了一下.提前需要学习的知识java反射.泛型 用到的反射如下: Class<T>类 是java.lang包下,Class类的实例表示 ...

  8. 自己动手写泛型dao

    在经过一系列的问题得到解决之后,泛型dao终于写出来了.泛型dao相比于以前写的dao最大的好处就是,大大提高了代码的复用性,以往我们要对数据库中表中的数据进行操作的时候,每张表都需要写一个dao来操 ...

  9. 浅谈Java——泛型DAO

    首先解释一下为什么要学习泛型DAO.平时在写DAO的时候是一个接口对应一个实现类,实现类里面要写很多的操作数据库的方法.当我们有很多的javaben的时候我们会写很多的接口和实现类,并且里面的代码都是 ...

随机推荐

  1. Unity3D开发(五):Unity3D 4.x 使用Mecanim实现连击(转)

    原地址:http://www.unitymanual.com/blog-1801-1221.html unity3d 4.x 版本之后提供了一种新的动画机制Mecanim,虽然目前还支持之前的Anim ...

  2. HDOJ-1999 不可摸数

    不可摸数 转自:http://www.cnblogs.com/dongsheng/archive/2012/08/18/2645594.html Time Limit: 2000/1000 MS (J ...

  3. POJ 1723

    #include <iostream> #include <algorithm> #define MAXN 10005 using namespace std; struct ...

  4. Class

    1. No const constructor Unlike other member functions, constructors may not be declared as const . W ...

  5. [转] ADO.NET实体框架引发争论

    转自:http://developer.51cto.com/art/200811/76356.htm 2008-11-11 14:00 朱永光译 infoq 我要评论(0) 一个在ADO.NET实体框 ...

  6. 0环境设置 - Statspack设置

    简单说明 Statspack主要用于永久存储performance statistics 信息 只有作为sysdba连接时才能安装Statspack. 然后改目录到#cd $ORACLE_HOME/r ...

  7. linux入门教程(一) 关于linux的历史

    很多关于linux的书籍在前面章节中写了一大堆东西来介绍linux,可惜读者看了好久也没有正式开始进入linux的世界,这样反而导致了他们对linux失去了一些兴趣,而把厚厚的一本书丢掉. Linux ...

  8. 包含中文的字符串中截取前N个字符

    package com.wangzhu.string; import java.io.UnsupportedEncodingException; public class SubStringDemo1 ...

  9. HTML5入门十---Canvas画布实现画图(一)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. NSRect

    #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { ...