一个好用的hibernate泛型dao

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

huidaoli

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值