Hibernate泛型Dao

来源:互联网 发布:mac air快捷键大全 编辑:程序博客网 时间:2024/05/16 17:20

以前从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 BookManagerextends 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接口不变就不要修改业务层的代码了。
代码如下(从下到上):

Page.Java

 

  1. package com.demonstration.hibernate.dao.support;
  2. import java.io.Serializable;
  3. import java.util.ArrayList;
  4. /**
  5.  * 分页对象. 包含当前页数据及分页信息如总记录数.
  6.  *
  7.  * @author springside
  8.  * 
  9.  */
  10. @SuppressWarnings("serial")
  11. public class Page implements Serializable {
  12.     private static int DEFAULT_PAGE_SIZE = 20;
  13.     private int pageSize = DEFAULT_PAGE_SIZE; // 每页的记录数
  14.     private long start; // 当前页第一条数据在List中的位置,从0开始
  15.     private Object data; // 当前页中存放的记录,类型一般为List
  16.     private long totalCount; // 总记录数
  17.     /**
  18.      * 构造方法,只构造空页.
  19.      */
  20.     @SuppressWarnings("unchecked")
  21.     public Page() {
  22.         this(0, 0, DEFAULT_PAGE_SIZE, new ArrayList());
  23.     }
  24.     /**
  25.      * 默认构造方法.
  26.      *
  27.      * @param start  本页数据在数据库中的起始位置
  28.      * @param totalSize 数据库中总记录条数
  29.      * @param pageSize  本页容量
  30.      * @param data    本页包含的数据
  31.      */
  32.     public Page(long start, long totalSize, int pageSize, Object data) {
  33.         this.pageSize = pageSize;
  34.         this.start = start;
  35.         this.totalCount = totalSize;
  36.         this.data = data;
  37.     }
  38.     /**
  39.      * 取总记录数.
  40.      */
  41.     public long getTotalCount() {
  42.         return this.totalCount;
  43.     }
  44.     /**
  45.      * 取总页数.
  46.      */
  47.     public long getTotalPageCount() {
  48.         if (totalCount % pageSize == 0)
  49.             return totalCount / pageSize;
  50.         else
  51.             return totalCount / pageSize + 1;
  52.     }
  53.     /**
  54.      * 取每页数据容量.
  55.      */
  56.     public int getPageSize() {
  57.         return pageSize;
  58.     }
  59.     /**
  60.      * 取当前页中的记录.
  61.      */
  62.     public Object getResult() {
  63.         return data;
  64.     }
  65.     /**
  66.      * 取该页当前页码,页码从1开始.
  67.      */
  68.     public long getCurrentPageNo() {
  69.         return start / pageSize + 1;
  70.     }
  71.     /**
  72.      * 该页是否有下一页.
  73.      */
  74.     public boolean hasNextPage() {
  75.         return this.getCurrentPageNo() < this.getTotalPageCount() - 1;
  76.     }
  77.     /**
  78.      * 该页是否有上一页.
  79.      */
  80.     public boolean hasPreviousPage() {
  81.         return this.getCurrentPageNo() > 1;
  82.     }
  83.     /**
  84.      * 获取任一页第一条数据在数据集的位置,每页条数使用默认值.
  85.      *
  86.      * @see #getStartOfPage(int,int)
  87.      */
  88.     protected static int getStartOfPage(int pageNo) {
  89.         return getStartOfPage(pageNo, DEFAULT_PAGE_SIZE);
  90.     }
  91.     /**
  92.      * 获取任一页第一条数据在数据集的位置.
  93.      *
  94.      * @param pageNo   从1开始的页号
  95.      * @param pageSize 每页记录条数
  96.      * @return 该页第一条数据
  97.      */
  98.     public static int getStartOfPage(int pageNo, int pageSize) {
  99.         return (pageNo - 1) * pageSize;
  100.     }
  101. }
GenericsUtils.java

 

 

  1. package com.demonstration.hibernate.dao.support;
  2. import java.lang.reflect.ParameterizedType;
  3. import java.lang.reflect.Type;
  4. import org.apache.commons.logging.Log;
  5. import org.apache.commons.logging.LogFactory;
  6. /**
  7.  * Generics的util类.
  8.  *
  9.  * @author springside
  10.  * 
  11.  */
  12. public class GenericsUtils {
  13.     private static final Log log = LogFactory.getLog(GenericsUtils.class);
  14.     private GenericsUtils() {
  15.     }
  16.     /**
  17.      * 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends GenricManager<Book>
  18.      *
  19.      * @param clazz The class to introspect
  20.      * @return the first generic declaration, or <code>Object.class</code> if cannot be determined
  21.      */
  22.     @SuppressWarnings("unchecked")
  23.     public static Class getSuperClassGenricType(Class clazz) {
  24.         return getSuperClassGenricType(clazz, 0);
  25.     }
  26.     /**
  27.      * 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends GenricManager<Book>
  28.      *
  29.      * @param clazz clazz The class to introspect
  30.      * @param index the Index of the generic ddeclaration,start from 0.
  31.      * @return the index generic declaration, or <code>Object.class</code> if cannot be determined
  32.      */
  33.     @SuppressWarnings("unchecked")
  34.     public static Class getSuperClassGenricType(Class clazz, int index) {
  35.         Type genType = clazz.getGenericSuperclass();
  36.         if (!(genType instanceof ParameterizedType)) {
  37.             log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
  38.             return Object.class;
  39.         }
  40.         Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
  41.         if (index >= params.length || index < 0) {
  42.             log.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
  43.                     + params.length);
  44.             return Object.class;
  45.         }
  46.         if (!(params[index] instanceof Class)) {
  47.             log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
  48.             return Object.class;
  49.         }
  50.         return (Class) params[index];
  51.     }
  52. }

 

BeanUtils.java

 

  1. package com.demonstration.hibernate.dao.support;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.Method;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import org.apache.commons.lang.StringUtils;
  7. import org.apache.commons.logging.Log;
  8. import org.apache.commons.logging.LogFactory;
  9. import org.springframework.util.Assert;
  10. import org.springframework.util.ReflectionUtils;
  11. /**
  12.  * 扩展Apache Commons BeanUtils, 提供一些反射方面缺失功能的封装.
  13.  * @author springside
  14.  * 
  15.  */
  16. public class BeanUtils extends org.apache.commons.beanutils.BeanUtils {
  17.     protected static final Log logger = LogFactory.getLog(BeanUtils.class);
  18.     private BeanUtils() {
  19.     }
  20.     /**
  21.      * 循环向上转型,获取对象的DeclaredField.
  22.      *
  23.      * @throws NoSuchFieldException 如果没有该Field时抛出.
  24.      */
  25.     public static Field getDeclaredField(Object object, String propertyName) throws NoSuchFieldException {
  26.         Assert.notNull(object);
  27.         Assert.hasText(propertyName);
  28.         return getDeclaredField(object.getClass(), propertyName);
  29.     }
  30.     /**
  31.      * 循环向上转型,获取对象的DeclaredField.
  32.      *
  33.      * @throws NoSuchFieldException 如果没有该Field时抛出.
  34.      */
  35.     @SuppressWarnings("unchecked")
  36.     public static Field getDeclaredField(Class clazz, String propertyName) throws NoSuchFieldException {
  37.         Assert.notNull(clazz);
  38.         Assert.hasText(propertyName);
  39.         for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
  40.             try {
  41.                 return superClass.getDeclaredField(propertyName);
  42.             } catch (NoSuchFieldException e) {
  43.                 // Field不在当前类定义,继续向上转型
  44.             }
  45.         }
  46.         throw new NoSuchFieldException("No such field: " + clazz.getName() + '.' + propertyName);
  47.     }
  48.     /**
  49.      * 暴力获取对象变量值,忽略private,protected修饰符的限制.
  50.      *
  51.      * @throws NoSuchFieldException 如果没有该Field时抛出.
  52.      */
  53.     public static Object forceGetProperty(Object object, String propertyName) throws NoSuchFieldException {
  54.         Assert.notNull(object);
  55.         Assert.hasText(propertyName);
  56.         Field field = getDeclaredField(object, propertyName);
  57.         boolean accessible = field.isAccessible();
  58.         field.setAccessible(true);
  59.         Object result = null;
  60.         try {
  61.             result = field.get(object);
  62.         } catch (IllegalAccessException e) {
  63.             logger.info("error wont' happen");
  64.         }
  65.         field.setAccessible(accessible);
  66.         return result;
  67.     }
  68.     /**
  69.      * 暴力设置对象变量值,忽略private,protected修饰符的限制.
  70.      *
  71.      * @throws NoSuchFieldException 如果没有该Field时抛出.
  72.      */
  73.     public static void forceSetProperty(Object object, String propertyName, Object newValue)
  74.             throws NoSuchFieldException {
  75.         Assert.notNull(object);
  76.         Assert.hasText(propertyName);
  77.         Field field = getDeclaredField(object, propertyName);
  78.         boolean accessible = field.isAccessible();
  79.         field.setAccessible(true);
  80.         try {
  81.             field.set(object, newValue);
  82.         } catch (IllegalAccessException e) {
  83.             logger.info("Error won't happen");
  84.         }
  85.         field.setAccessible(accessible);
  86.     }
  87.     /**
  88.      * 暴力调用对象函数,忽略private,protected修饰符的限制.
  89.      *
  90.      * @throws NoSuchMethodException 如果没有该Method时抛出.
  91.      */
  92.     @SuppressWarnings("unchecked")
  93.     public static Object invokePrivateMethod(Object object, String methodName, Object... params)
  94.             throws NoSuchMethodException {
  95.         Assert.notNull(object);
  96.         Assert.hasText(methodName);
  97.         Class[] types = new Class[params.length];
  98.         for (int i = 0; i < params.length; i++) {
  99.             types[i] = params[i].getClass();
  100.         }
  101.         Class clazz = object.getClass();
  102.         Method method = null;
  103.         for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
  104.             try {
  105.                 method = superClass.getDeclaredMethod(methodName, types);
  106.                 break;
  107.             } catch (NoSuchMethodException e) {
  108.                 // 方法不在当前类定义,继续向上转型
  109.             }
  110.         }
  111.         if (method == null)
  112.             throw new NoSuchMethodException("No Such Method:" + clazz.getSimpleName() + methodName);
  113.         boolean accessible = method.isAccessible();
  114.         method.setAccessible(true);
  115.         Object result = null;
  116.         try {
  117.             result = method.invoke(object, params);
  118.         } catch (Exception e) {
  119.             ReflectionUtils.handleReflectionException(e);
  120.         }
  121.         method.setAccessible(accessible);
  122.         return result;
  123.     }
  124.     /**
  125.      * 按Filed的类型取得Field列表.
  126.      */
  127.     @SuppressWarnings("unchecked")
  128.     public static List<Field> getFieldsByType(Object object, Class type) {
  129.         List<Field> list = new ArrayList<Field>();
  130.         Field[] fields = object.getClass().getDeclaredFields();
  131.         for (Field field : fields) {
  132.             if (field.getType().isAssignableFrom(type)) {
  133.                 list.add(field);
  134.             }
  135.         }
  136.         return list;
  137.     }
  138.     /**
  139.      * 按FiledName获得Field的类型.
  140.      */
  141.     @SuppressWarnings("unchecked")
  142.     public static Class getPropertyType(Class type, String name) throws NoSuchFieldException {
  143.         return getDeclaredField(type, name).getType();
  144.     }
  145.     /**
  146.      * 获得field的getter函数名称.
  147.      */
  148.     @SuppressWarnings("unchecked")
  149.     public static String getGetterName(Class type, String fieldName) {
  150.         Assert.notNull(type, "Type required");
  151.         Assert.hasText(fieldName, "FieldName required");
  152.         if (type.getName().equals("boolean")) {
  153.             return "is" + StringUtils.capitalize(fieldName);
  154.         } else {
  155.             return "get" + StringUtils.capitalize(fieldName);
  156.         }
  157.     }
  158.     /**
  159.      * 获得field的getter函数,如果找不到该方法,返回null.
  160.      */
  161.     @SuppressWarnings("unchecked")
  162.     public static Method getGetterMethod(Class type, String fieldName) {
  163.         try {
  164.             return type.getMethod(getGetterName(type, fieldName));
  165.         } catch (NoSuchMethodException e) {
  166.             logger.error(e.getMessage(), e);
  167.         }
  168.         return null;
  169.     }
  170. }

 

IUndeleteableEntityOperation.java

 

  1. package com.demonstration.hibernate.dao.extend;
  2. import java.util.List;
  3. import org.hibernate.criterion.Criterion;
  4. /**
  5.  * 定义如果支持Entity不被直接删除必须支持的Operation.
  6.  *
  7.  * @author springside
  8.  * 
  9.  */
  10. public interface IUndeleteableEntityOperation<T> {
  11.     /*
  12.      * Undelete Entity用到的几个常量,因为要同时兼顾Interface与Annotation,所以集中放此.
  13.      */
  14.     String UNVALID_VALUE = "-1";
  15.     String NORMAL_VALUE = "0";
  16.     String STATUS = "status";
  17.     /**
  18.      * 取得所有状态为有效的对象.
  19.      */
  20.     List<T> getAllValid();
  21.     /**
  22.      * 删除对象,但如果是Undeleteable的entity,设置对象的状态而不是直接删除.
  23.      */
  24.     void remove(Object entity);
  25.     /**
  26.      * 获取过滤已删除对象的hql条件语句.
  27.      */
  28.     String getUnDeletableHQL();
  29.     /**
  30.      * 获取过滤已删除对象的Criterion条件语句.
  31.      */
  32.     Criterion getUnDeletableCriterion();
  33. }
IUndeletableEntity.java

 

 

  1. package com.demonstration.hibernate.dao.extend;
  2. /**
  3.  * 标识商业对象不能被删除,只能被设为无效的接口.
  4.  *
  5.  * @author springside
  6.  * 
  7.  */
  8. public interface IUndeletableEntity {
  9.     void setStatus(String status);
  10. }
IUndeletable.java

 

 

  1. package com.demonstration.hibernate.dao.extend;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. /**
  7.  * 标识商业对象不能被删除,只能被设为无效的Annoation.
  8.  * <p/>
  9.  * 相比inferface的标示方式,annotation 方式更少侵入性,可以定义任意属性代表status,而默认为status属性.
  10.  */
  11. @Target({ElementType.TYPE})
  12. @Retention(RetentionPolicy.RUNTIME)
  13. public @interface IUndeletable {
  14.     String status() default IUndeleteableEntityOperation.STATUS;
  15. }
HibernateEntityExtendDao.java

 

 

  1. package com.demonstration.hibernate.dao.extend;
  2. import java.util.List;
  3. import java.util.Map;
  4. import org.apache.commons.beanutils.PropertyUtils;
  5. import org.hibernate.Criteria;
  6. import org.hibernate.criterion.Criterion;
  7. import org.hibernate.criterion.Restrictions;
  8. import org.springframework.util.Assert;
  9. import org.springframework.util.ReflectionUtils;
  10. import com.demonstration.hibernate.dao.HibernateEntityDao;
  11. /**
  12.  * 加强版的entity dao.
  13.  * <p>自动处理Undeletable Entity.<br>
  14.  * Undeletable Entity 在删除时只把状态设为无效,不会真正执行删除.<br>
  15.  * Undeletable Entity 可以通过annotation或接口两种形式来声明.<br>
  16.  * 其中annotation模式不限制状态列的属性名必须为"status",可以用注释来确定任意属性为状态属性.<br>
  17.  * </p>
  18.  *
  19.  * @author springside
  20.  *
  21.  * @see HibernateEntityDao
  22.  * @see EntityInfo
  23.  * @see IUndeleteableEntityOperation
  24.  * @see IUndeletable
  25.  * @see IUndeletableEntity
  26.  */
  27. @SuppressWarnings("unchecked")
  28. public class HibernateEntityExtendDao<T> extends HibernateEntityDao<T> implements IUndeleteableEntityOperation<T> {
  29.     /**
  30.      * 保存所管理的Entity的信息.
  31.      */
  32.     protected EntityInfo entityInfo;
  33.     /**
  34.      * 构造函数,初始化entity信息.
  35.      */
  36.     public HibernateEntityExtendDao() {
  37.         entityInfo = new EntityInfo(entityClass);
  38.     }
  39.     /**
  40.      * 取得所有状态为有效的对象.
  41.      *
  42.      * @see IUndeleteableEntityOperation#getAllValid()
  43.      */
  44.     public List<T> getAllValid() {
  45.         Criteria criteria = createCriteria();
  46.         if (entityInfo.isUndeletable)
  47.             criteria.add(getUnDeletableCriterion());
  48.         return criteria.list();
  49.     }
  50.     /**
  51.      * 获取过滤已删除对象的hql条件语句.
  52.      *
  53.      * @see IUndeleteableEntityOperation#getUnDeletableHQL()
  54.      */
  55.     public String getUnDeletableHQL() {
  56.         return entityInfo.statusProperty + "<>" + UNVALID_VALUE;
  57.     }
  58.     /**
  59.      * 获取过滤已删除对象的Criterion条件语句.
  60.      *
  61.      * @see UndeleteableEntityOperation#
  62.      */
  63.     public Criterion getUnDeletableCriterion() {
  64.         return Restrictions.not(Restrictions.eq(entityInfo.statusProperty, UNVALID_VALUE));
  65.     }
  66.     /**
  67.      * 重载保存函数,在保存前先调用onValid(T),进行书名不重复等数据库相关的校验.
  68.      *
  69.      * @see #onValid(Object)
  70.      * @see HibernateEntityDao#save(Object)
  71.      */
  72.     @Override
  73.     public void save(Object entity) {
  74.         Assert.isInstanceOf(getEntityClass(), entity);
  75.         onValid((T) entity);
  76.         super.save(entity);
  77.     }
  78.     /**
  79.      * 删除对象,如果是Undeleteable的entity,设置对象的状态而不是直接删除.
  80.      *
  81.      * @see HibernateEntityDao#remove(Object)
  82.      */
  83.     @Override
  84.     public void remove(Object entity) {
  85.         if (entityInfo.isUndeletable) {
  86.             try {
  87.                 PropertyUtils.setProperty(entity, entityInfo.statusProperty, UNVALID_VALUE);
  88.                 save(entity);
  89.             } catch (Exception e) {
  90.                 ReflectionUtils.handleReflectionException(e);
  91.             }
  92.         } else
  93.             super.remove(entity);
  94.     }
  95.     /**
  96.      * 与数据库相关的校验,比如判断名字在数据库里有没有重复, 在保存时被调用,在子类重载.
  97.      *
  98.      * @see #save(Object)
  99.      */
  100.     public void onValid(T entity) {
  101.     }
  102.     /**
  103.      * 根据Map中的条件的Criteria查询.
  104.      *
  105.      * @param map Map中仅包含条件名与条件值,默认全部相同,可重载。
  106.      */
  107.     public List<T> find(Map map) {
  108.         Criteria criteria = createCriteria();
  109.         return find(criteria, map);
  110.     }
  111.     /**
  112.      * 根据Map中的条件的Criteria查询.
  113.      *
  114.      * @param map Map中仅包含条件名与条件值,默认全部相同,可重载.
  115.      */
  116.     public List<T> find(Criteria criteria, Map map) {
  117.         Assert.notNull(criteria);
  118.         criteria.add(Restrictions.allEq(map));
  119.         return criteria.list();
  120.     }
  121. }

 

 

EntityInfo.java
  1. package com.demonstration.hibernate.dao.extend;
  2. /**
  3.  * 装载Entity信息的内部类.
  4.  *
  5.  * @author springside
  6.  * 
  7.  */
  8. class EntityInfo {
  9.     boolean isUndeletable = false// entity是否undeleteable的标志
  10.     String statusProperty; // 标识状态的属性名
  11.     @SuppressWarnings("unchecked")
  12.     public EntityInfo(Class entityClass) {
  13.         init(entityClass);
  14.     }
  15.     /**
  16.      * 初始函数,判断EntityClass是否UndeletableEntity.
  17.      */
  18.     @SuppressWarnings("unchecked")
  19.     private void init(Class entityClass) {
  20.         // 通过EntityClass的interface判断entity是否undeletable
  21.         if (IUndeletableEntity.class.isAssignableFrom(entityClass)) {
  22.             isUndeletable = true;
  23.             statusProperty = IUndeleteableEntityOperation.STATUS;
  24.         }
  25.         // 通过EntityClass的annotation判断entity是否undeletable
  26.         if (entityClass.isAnnotationPresent(IUndeletable.class)) {
  27.             isUndeletable = true;
  28.             IUndeletable anno = (IUndeletable) entityClass.getAnnotation(IUndeletable.class);
  29.             statusProperty = anno.status();
  30.         }
  31.     }
  32. }
IEntityDao.java
  1. package com.demonstration.hibernate.dao;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. /**
  5.  * 针对单个Entity对象的操作定义.不依赖于具体ORM实现方案.
  6.  *
  7.  * @author springside
  8.  *
  9.  */
  10. public interface IEntityDao<T> {
  11.     T get(Serializable id);
  12.     List<T> getAll();
  13.     void save(Object o);
  14.     void remove(Object o);
  15.     void removeById(Serializable id);
  16.     /**
  17.      * 获取Entity对象的主键名.
  18.      */
  19.     @SuppressWarnings("unchecked")
  20.     String getIdName(Class clazz);
  21. }
HibernateGenericDao.java
  1. package com.demonstration.hibernate.dao;
  2. import java.io.Serializable;
  3. import java.lang.reflect.InvocationTargetException;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import java.util.regex.Matcher;
  7. import java.util.regex.Pattern;
  8. import org.apache.commons.beanutils.PropertyUtils;
  9. import org.hibernate.Criteria;
  10. import org.hibernate.Query;
  11. import org.hibernate.criterion.CriteriaSpecification;
  12. import org.hibernate.criterion.Criterion;
  13. import org.hibernate.criterion.DetachedCriteria;
  14. import org.hibernate.criterion.Order;
  15. import org.hibernate.criterion.Projection;
  16. import org.hibernate.criterion.Projections;
  17. import org.hibernate.criterion.Restrictions;
  18. import org.hibernate.impl.CriteriaImpl;
  19. import org.hibernate.metadata.ClassMetadata;
  20. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
  21. import org.springframework.util.Assert;
  22. import org.springframework.util.ReflectionUtils;
  23. import com.demonstration.hibernate.dao.support.BeanUtils;
  24. import com.demonstration.hibernate.dao.support.Page;
  25. /**
  26.  * Hibernate Dao的泛型基类.
  27.  * <p/>
  28.  * 继承于Spring的<code>HibernateDaoSupport</code>,提供分页函数和若干便捷查询方法,并对返回值作了泛型类型转换.
  29.  *
  30.  * @author springside
  31.  * 
  32.  * @see HibernateDaoSupport
  33.  * @see HibernateEntityDao
  34.  */
  35. @SuppressWarnings("unchecked")
  36. public class HibernateGenericDao extends HibernateDaoSupport {
  37.     /**
  38.      * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
  39.      */
  40.     public <T> T get(Class<T> entityClass, Serializable id) {
  41.         return (T) getHibernateTemplate().load(entityClass, id);
  42.     }
  43.     /**
  44.      * 获取全部对象.
  45.      */
  46.     public <T> List<T> getAll(Class<T> entityClass) {
  47.         return getHibernateTemplate().loadAll(entityClass);
  48.     }
  49.     /**
  50.      * 获取全部对象,带排序字段与升降序参数.
  51.      */
  52.     public <T> List<T> getAll(Class<T> entityClass, String orderBy, boolean isAsc) {
  53.         Assert.hasText(orderBy);
  54.         if (isAsc)
  55.             return getHibernateTemplate().findByCriteria(
  56.                     DetachedCriteria.forClass(entityClass).addOrder(Order.asc(orderBy)));
  57.         else
  58.             return getHibernateTemplate().findByCriteria(
  59.                     DetachedCriteria.forClass(entityClass).addOrder(Order.desc(orderBy)));
  60.     }
  61.     /**
  62.      * 保存对象.
  63.      */
  64.     public void save(Object o) {
  65.         getHibernateTemplate().saveOrUpdate(o);
  66.     }
  67.     /**
  68.      * 删除对象.
  69.      */
  70.     public void remove(Object o) {
  71.         getHibernateTemplate().delete(o);
  72.     }
  73.     /**
  74.      * 根据ID删除对象.
  75.      */
  76.     public <T> void removeById(Class<T> entityClass, Serializable id) {
  77.         remove(get(entityClass, id));
  78.     }
  79.     public void flush() {
  80.         getHibernateTemplate().flush();
  81.     }
  82.     public void clear() {
  83.         getHibernateTemplate().clear();
  84.     }
  85.     /**
  86.      * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
  87.      * 留意可以连续设置,如下:
  88.      * <pre>
  89.      * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
  90.      * </pre>
  91.      * 调用方式如下:
  92.      * <pre>
  93.      *        dao.createQuery(hql)
  94.      *        dao.createQuery(hql,arg0);
  95.      *        dao.createQuery(hql,arg0,arg1);
  96.      *        dao.createQuery(hql,new Object[arg0,arg1,arg2])
  97.      * </pre>
  98.      *
  99.      * @param values 可变参数.
  100.      */
  101.     public Query createQuery(String hql, Object... values) {
  102.         Assert.hasText(hql);
  103.         Query query = getSession().createQuery(hql);
  104.         for (int i = 0; i < values.length; i++) {
  105.             query.setParameter(i, values[i]);
  106.         }
  107.         return query;
  108.     }
  109.     /**
  110.      * 创建Criteria对象.
  111.      *
  112.      * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)}
  113.      */
  114.     public <T> Criteria createCriteria(Class<T> entityClass, Criterion... criterions) {
  115.         Criteria criteria = getSession().createCriteria(entityClass);
  116.         for (Criterion c : criterions) {
  117.             criteria.add(c);
  118.         }
  119.         return criteria;
  120.     }
  121.     /**
  122.      * 创建Criteria对象,带排序字段与升降序字段.
  123.      *
  124.      * @see #createCriteria(Class,Criterion[])
  125.      */
  126.     public <T> Criteria createCriteria(Class<T> entityClass, String orderBy, boolean isAsc, Criterion... criterions) {
  127.         Assert.hasText(orderBy);
  128.         Criteria criteria = createCriteria(entityClass, criterions);
  129.         if (isAsc)
  130.             criteria.addOrder(Order.asc(orderBy));
  131.         else
  132.             criteria.addOrder(Order.desc(orderBy));
  133.         return criteria;
  134.     }
  135.     /**
  136.      * 根据hql查询,直接使用HibernateTemplate的find函数.
  137.      *
  138.      * @param values 可变参数,见{@link #createQuery(String,Object...)}
  139.      */
  140.     public List find(String hql, Object... values) {
  141.         Assert.hasText(hql);
  142.         return getHibernateTemplate().find(hql, values);
  143.     }
  144.     /**
  145.      * 根据属性名和属性值查询对象.
  146.      *
  147.      * @return 符合条件的对象列表
  148.      */
  149.     public <T> List<T> findBy(Class<T> entityClass, String propertyName, Object value) {
  150.         Assert.hasText(propertyName);
  151.         return createCriteria(entityClass, Restrictions.eq(propertyName, value)).list();
  152.     }
  153.     /**
  154.      * 根据属性名和属性值查询对象,带排序参数.
  155.      */
  156.     public <T> List<T> findBy(Class<T> entityClass, String propertyName, Object value, String orderBy, boolean isAsc) {
  157.         Assert.hasText(propertyName);
  158.         Assert.hasText(orderBy);
  159.         return createCriteria(entityClass, orderBy, isAsc, Restrictions.eq(propertyName, value)).list();
  160.     }
  161.     /**
  162.      * 根据属性名和属性值查询唯一对象.
  163.      *
  164.      * @return 符合条件的唯一对象 or null if not found.
  165.      */
  166.     public <T> T findUniqueBy(Class<T> entityClass, String propertyName, Object value) {
  167.         Assert.hasText(propertyName);
  168.         return (T) createCriteria(entityClass, Restrictions.eq(propertyName, value)).uniqueResult();
  169.     }
  170.     /**
  171.      * 分页查询函数,使用hql.
  172.      *
  173.      * @param pageNo 页号,从1开始.
  174.      */
  175.     public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values) {
  176.         Assert.hasText(hql);
  177.         Assert.isTrue(pageNo >= 1, "pageNo should start from 1");
  178.         // Count查询
  179.         String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
  180.         List countlist = getHibernateTemplate().find(countQueryString, values);
  181.         long totalCount = (Long) countlist.get(0);
  182.         if (totalCount < 1)
  183.             return new Page();
  184.         // 实际查询返回分页对象
  185.         int startIndex = Page.getStartOfPage(pageNo, pageSize);
  186.         Query query = createQuery(hql, values);
  187.         List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
  188.         return new Page(startIndex, totalCount, pageSize, list);
  189.     }
  190.     
  191.      /**
  192.      * @author Scott.wanglei
  193.      * @since  2008-7-21
  194.      * @param hql 查询sql
  195.      * @param start 分页从哪一条数据开始
  196.      * @param pageSize 每一个页面的大小
  197.      * @param values 查询条件
  198.      * @return page对象
  199.      */
  200.     public Page dataQuery(String hql, int start, int pageSize, Object... values){
  201.         // Count查询
  202.         String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
  203.         List countlist = getHibernateTemplate().find(countQueryString, values);
  204.         long totalCount = (Long) countlist.get(0);
  205.         if (totalCount < 1)
  206.             return new Page();
  207.         // 实际查询返回分页对象
  208.         int startIndex = start;
  209.         Query query = createQuery(hql, values);
  210.         List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
  211.         return new Page(startIndex, totalCount, pageSize, list);
  212.      }
  213.     /**
  214.      * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
  215.      *
  216.      * @param pageNo 页号,从1开始.
  217.      * @return 含总记录数和当前页数据的Page对象.
  218.      */
  219.     public Page pagedQuery(Criteria criteria, int pageNo, int pageSize) {
  220.         Assert.notNull(criteria);
  221.         Assert.isTrue(pageNo >= 1, "pageNo should start from 1");
  222.         CriteriaImpl impl = (CriteriaImpl) criteria;
  223.         // 先把Projection和OrderBy条件取出来,清空两者来执行Count操作
  224.         Projection projection = impl.getProjection();
  225.         List<CriteriaImpl.OrderEntry> orderEntries;
  226.         try {
  227.             orderEntries = (List) BeanUtils.forceGetProperty(impl, "orderEntries");
  228.             BeanUtils.forceSetProperty(impl, "orderEntries"new ArrayList());
  229.         } catch (Exception e) {
  230.             throw new InternalError(" Runtime Exception impossibility throw ");
  231.         }
  232.         // 执行查询
  233.         int totalCount = (Integer) criteria.setProjection(Projections.rowCount()).uniqueResult();
  234.         // 将之前的Projection和OrderBy条件重新设回去
  235.         criteria.setProjection(projection);
  236.         if (projection == null) {
  237.             criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
  238.         }
  239.         try {
  240.             BeanUtils.forceSetProperty(impl, "orderEntries", orderEntries);
  241.         } catch (Exception e) {
  242.             throw new InternalError(" Runtime Exception impossibility throw ");
  243.         }
  244.         // 返回分页对象
  245.         if (totalCount < 1)
  246.             return new Page();
  247.         int startIndex = Page.getStartOfPage(pageNo, pageSize);;
  248.         List list = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();
  249.         return new Page(startIndex, totalCount, pageSize, list);
  250.     }
  251.     /**
  252.      * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
  253.      *
  254.      * @param pageNo 页号,从1开始.
  255.      * @return 含总记录数和当前页数据的Page对象.
  256.      */
  257.     public Page pagedQuery(Class entityClass, int pageNo, int pageSize, Criterion... criterions) {
  258.         Criteria criteria = createCriteria(entityClass, criterions);
  259.         return pagedQuery(criteria, pageNo, pageSize);
  260.     }
  261.     /**
  262.      * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
  263.      *
  264.      * @param pageNo 页号,从1开始.
  265.      * @return 含总记录数和当前页数据的Page对象.
  266.      */
  267.     public Page pagedQuery(Class entityClass, int pageNo, int pageSize, String orderBy, boolean isAsc,
  268.                            Criterion... criterions) {
  269.         Criteria criteria = createCriteria(entityClass, orderBy, isAsc, criterions);
  270.         return pagedQuery(criteria, pageNo, pageSize);
  271.     }
  272.     /**
  273.      * 判断对象某些属性的值在数据库中是否唯一.
  274.      *
  275.      * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  276.      */
  277.     public <T> boolean isUnique(Class<T> entityClass, Object entity, String uniquePropertyNames) {
  278.         Assert.hasText(uniquePropertyNames);
  279.         Criteria criteria = createCriteria(entityClass).setProjection(Projections.rowCount());
  280.         String[] nameList = uniquePropertyNames.split(",");
  281.         try {
  282.             // 循环加入唯一列
  283.             for (String name : nameList) {
  284.                 criteria.add(Restrictions.eq(name, PropertyUtils.getProperty(entity, name)));
  285.             }
  286.             // 以下代码为了如果是update的情况,排除entity自身.
  287.             String idName = getIdName(entityClass);
  288.             // 取得entity的主键值
  289.             Serializable id = getId(entityClass, entity);
  290.             // 如果id!=null,说明对象已存在,该操作为update,加入排除自身的判断
  291.             if (id != null)
  292.                 criteria.add(Restrictions.not(Restrictions.eq(idName, id)));
  293.         } catch (Exception e) {
  294.             ReflectionUtils.handleReflectionException(e);
  295.         }
  296.         return (Integer) criteria.uniqueResult() == 0;
  297.     }
  298.     /**
  299.      * 取得对象的主键值,辅助函数.
  300.      */
  301.     public Serializable getId(Class entityClass, Object entity) throws NoSuchMethodException, IllegalAccessException,
  302.             InvocationTargetException {
  303.         Assert.notNull(entity);
  304.         Assert.notNull(entityClass);
  305.         return (Serializable) PropertyUtils.getProperty(entity, getIdName(entityClass));
  306.     }
  307.     /**
  308.      * 取得对象的主键名,辅助函数.
  309.      */
  310.     public String getIdName(Class clazz) {
  311.         Assert.notNull(clazz);
  312.         ClassMetadata meta = getSessionFactory().getClassMetadata(clazz);
  313.         Assert.notNull(meta, "Class " + clazz + " not define in hibernate session factory.");
  314.         String idName = meta.getIdentifierPropertyName();
  315.         Assert.hasText(idName, clazz.getSimpleName() + " has no identifier property define.");
  316.         return idName;
  317.     }
  318.     /**
  319.      * 去除hql的select 子句,未考虑union的情况,用于pagedQuery.
  320.      *
  321.      * @see #pagedQuery(String,int,int,Object[])
  322.      */
  323.     private static String removeSelect(String hql) {
  324.         Assert.hasText(hql);
  325.         int beginPos = hql.toLowerCase().indexOf("from");
  326.         Assert.isTrue(beginPos != -1, " hql : " + hql + " must has a keyword 'from'");
  327.         return hql.substring(beginPos);
  328.     }
  329.     /**
  330.      * 去除hql的orderby 子句,用于pagedQuery.
  331.      *
  332.      * @see #pagedQuery(String,int,int,Object[])
  333.      */
  334.     private static String removeOrders(String hql) {
  335.         Assert.hasText(hql);
  336.         Pattern p = Pattern.compile("order//s*by[//w|//W|//s|//S]*", Pattern.CASE_INSENSITIVE);
  337.         Matcher m = p.matcher(hql);
  338.         StringBuffer sb = new StringBuffer();
  339.         while (m.find()) {
  340.             m.appendReplacement(sb, "");
  341.         }
  342.         m.appendTail(sb);
  343.         return sb.toString();
  344.     }
  345.     
  346. }
HibernateEntityDao.java
  1. package com.demonstration.hibernate.dao;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. import org.hibernate.Criteria;
  5. import org.hibernate.criterion.Criterion;
  6. import com.demonstration.hibernate.dao.support.GenericsUtils;
  7. /**
  8.  * 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类. <p/> 子类只要在类定义时指定所管理Entity的Class,
  9.  * 即拥有对单个Entity对象的CRUD操作.
  10.  * 
  11.  * <pre>
  12.  * public class UserManager extends HibernateEntityDao<User> {
  13.  * }
  14.  * </pre>
  15.  * 
  16.  * @author springside
  17.  * 
  18.  * @see HibernateGenericDao
  19.  */
  20. @SuppressWarnings("unchecked")
  21. public class HibernateEntityDao<T> extends HibernateGenericDao implements
  22.         IEntityDao<T> {
  23.     protected Class<T> entityClass;// DAO所管理的Entity类型.
  24.     /**
  25.      * 在构造函数中将泛型T.class赋给entityClass.
  26.      */
  27.     public HibernateEntityDao() {
  28.         entityClass = GenericsUtils.getSuperClassGenricType(getClass());
  29.     }
  30.     /**
  31.      * 重载构造函数 让spring提供构造函数注入
  32.      */
  33.     public HibernateEntityDao(Class<T> type) {
  34.         this.entityClass = type;
  35.     }
  36.     
  37.     /**
  38.      * 取得entityClass.JDK1.4不支持泛型的子类可以抛开Class<T> entityClass,重载此函数达到相同效果。
  39.      */
  40.     protected Class<T> getEntityClass() {
  41.         return entityClass;
  42.     }
  43.     
  44.     public void setEntityClass(Class<T> type){
  45.         this.entityClass=type;
  46.     }
  47.     /**
  48.      * 根据ID获取对象.
  49.      * 
  50.      * @see HibernateGenericDao#getId(Class,Object)
  51.      */
  52.     public T get(Serializable id) {
  53.         return get(getEntityClass(), id);
  54.     }
  55.     /**
  56.      * 获取全部对象
  57.      * 
  58.      * @see HibernateGenericDao#getAll(Class)
  59.      */
  60.     public List<T> getAll() {
  61.         return getAll(getEntityClass());
  62.     }
  63.     /**
  64.      * 获取全部对象,带排序参数.
  65.      * 
  66.      * @see HibernateGenericDao#getAll(Class,String,boolean)
  67.      */
  68.     public List<T> getAll(String orderBy, boolean isAsc) {
  69.         return getAll(getEntityClass(), orderBy, isAsc);
  70.     }
  71.     /**
  72.      * 根据ID移除对象.
  73.      * 
  74.      * @see HibernateGenericDao#removeById(Class,Serializable)
  75.      */
  76.     public void removeById(Serializable id) {
  77.         removeById(getEntityClass(), id);
  78.     }
  79.     /**
  80.      * 取得Entity的Criteria.
  81.      * 
  82.      * @see HibernateGenericDao#createCriteria(Class,Criterion[])
  83.      */
  84.     public Criteria createCriteria(Criterion... criterions) {
  85.         return createCriteria(getEntityClass(), criterions);
  86.     }
  87.     /**
  88.      * 取得Entity的Criteria,带排序参数.
  89.      * 
  90.      * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[])
  91.      */
  92.     public Criteria createCriteria(String orderBy, boolean isAsc,
  93.             Criterion... criterions) {
  94.         return createCriteria(getEntityClass(), orderBy, isAsc, criterions);
  95.     }
  96.     /**
  97.      * 根据属性名和属性值查询对象.
  98.      * 
  99.      * @return 符合条件的对象列表
  100.      * @see HibernateGenericDao#findBy(Class,String,Object)
  101.      */
  102.     public List<T> findBy(String propertyName, Object value) {
  103.         return findBy(getEntityClass(), propertyName, value);
  104.     }
  105.     /**
  106.      * 根据属性名和属性值查询对象,带排序参数.
  107.      * 
  108.      * @return 符合条件的对象列表
  109.      * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean)
  110.      */
  111.     public List<T> findBy(String propertyName, Object value, String orderBy,
  112.             boolean isAsc) {
  113.         return findBy(getEntityClass(), propertyName, value, orderBy, isAsc);
  114.     }
  115.     /**
  116.      * 根据属性名和属性值查询单个对象.
  117.      * 
  118.      * @return 符合条件的唯一对象 or null
  119.      * @see HibernateGenericDao#findUniqueBy(Class,String,Object)
  120.      */
  121.     public T findUniqueBy(String propertyName, Object value) {
  122.         return findUniqueBy(getEntityClass(), propertyName, value);
  123.     }
  124.     /**
  125.      * 判断对象某些属性的值在数据库中唯一.
  126.      * 
  127.      * @param uniquePropertyNames
  128.      *            在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  129.      * @see HibernateGenericDao#isUnique(Class,Object,String)
  130.      */
  131.     public boolean isUnique(Object entity, String uniquePropertyNames) {
  132.         return isUnique(getEntityClass(), entity, uniquePropertyNames);
  133.     }
  134.     /**
  135.      * 消除与 Hibernate Session 的关联
  136.      * 
  137.      * @param entity
  138.      */
  139.     public void evit(Object entity) {
  140.         getHibernateTemplate().evict(entity);
  141.     }
  142. }
IBaseDao.java
  1. /**
  2.  * 
  3.  */
  4. package com.demonstration.hibernate.basedao;
  5. import java.io.Serializable;
  6. import java.lang.reflect.InvocationTargetException;
  7. import java.util.List;
  8. import java.util.Map;
  9. import org.hibernate.Criteria;
  10. import org.hibernate.Query;
  11. import org.hibernate.criterion.Criterion;
  12. import com.demonstration.hibernate.dao.HibernateEntityDao;
  13. import com.demonstration.hibernate.dao.HibernateGenericDao;
  14. import com.demonstration.hibernate.dao.extend.IUndeleteableEntityOperation;
  15. import com.demonstration.hibernate.dao.support.Page;
  16. /**
  17.  * @author 
  18.  * 
  19.  * 提供hibernate dao的所有操作,
  20.  * 实现类由spring注入HibernateEntityDao和HibernateEntityExtendDao来实现
  21.  * 最大限度的解耦hibernate持久层的操作
  22.  */
  23. public interface IBaseDao<T> {
  24.     /**
  25.      * 根据ID获取对象.
  26.      * 
  27.      * @see HibernateGenericDao#getId(Class,Object)
  28.      */
  29.     public T get(Serializable id);
  30.     
  31.     /**
  32.      * 获取全部对象
  33.      * 
  34.      * @see HibernateGenericDao#getAll(Class)
  35.      */
  36.     public List<T> getAll();
  37.     
  38.     /**
  39.      * 获取全部对象,带排序参数.
  40.      * 
  41.      * @see HibernateGenericDao#getAll(Class,String,boolean)
  42.      */
  43.     public List<T> getAll(String orderBy, boolean isAsc);
  44.     
  45.     /**
  46.      * 根据ID移除对象.
  47.      * 
  48.      * @see HibernateGenericDao#removeById(Class,Serializable)
  49.      */
  50.     public void removeById(Serializable id);
  51.     
  52.     /**
  53.      * 取得Entity的Criteria.
  54.      * 
  55.      * @see HibernateGenericDao#createCriteria(Class,Criterion[])
  56.      */
  57.     public Criteria createCriteria(Criterion... criterions);
  58.     
  59.     /**
  60.      * 取得Entity的Criteria,带排序参数.
  61.      * 
  62.      * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[])
  63.      */
  64.     public Criteria createCriteria(String orderBy, boolean isAsc,
  65.             Criterion... criterions);
  66.     
  67.     /**
  68.      * 根据属性名和属性值查询对象.
  69.      * 
  70.      * @return 符合条件的对象列表
  71.      * @see HibernateGenericDao#findBy(Class,String,Object)
  72.      */
  73.     public List<T> findBy(String propertyName, Object value);
  74.     
  75.     /**
  76.      * 根据属性名和属性值查询对象,带排序参数.
  77.      * 
  78.      * @return 符合条件的对象列表
  79.      * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean)
  80.      */
  81.     public List<T> findBy(String propertyName, Object value, String orderBy,
  82.             boolean isAsc);
  83.     
  84.     /**
  85.      * 根据属性名和属性值查询单个对象.
  86.      * 
  87.      * @return 符合条件的唯一对象 or null
  88.      * @see HibernateGenericDao#findUniqueBy(Class,String,Object)
  89.      */
  90.     public T findUniqueBy(String propertyName, Object value);
  91.     
  92.     /**
  93.      * 判断对象某些属性的值在数据库中唯一.
  94.      * 
  95.      * @param uniquePropertyNames
  96.      *            在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  97.      * @see HibernateGenericDao#isUnique(Class,Object,String)
  98.      */
  99.     public boolean isUnique(Object entity, String uniquePropertyNames);
  100.     
  101.     /**
  102.      * 消除与 Hibernate Session 的关联
  103.      * 
  104.      * @param entity
  105.      */
  106.     public void evit(Object entity);
  107.     
  108.     /*******************************************************************************************/
  109.     
  110.     /**
  111.      * 取得所有状态为有效的对象.
  112.      *
  113.      * @see IUndeleteableEntityOperation#getAllValid()
  114.      */
  115.     public List<T> getAllValid();
  116.     
  117.     /**
  118.      * 获取过滤已删除对象的hql条件语句.
  119.      *
  120.      * @see IUndeleteableEntityOperation#getUnDeletableHQL()
  121.      */
  122.     public String getUnDeletableHQL();
  123.     
  124.     /**
  125.      * 获取过滤已删除对象的Criterion条件语句.
  126.      *
  127.      * @see UndeleteableEntityOperation#
  128.      */
  129.     public Criterion getUnDeletableCriterion();
  130.     
  131.     /**
  132.      * 重载保存函数,在保存前先调用onValid(T),进行书名不重复等数据库相关的校验.
  133.      *
  134.      * @see #onValid(Object)
  135.      * @see HibernateEntityDao#save(Object)
  136.      */
  137.     public void saveOnValid(Object entity);
  138.     
  139.     /**
  140.      * 删除对象,如果是Undeleteable的entity,设置对象的状态而不是直接删除.
  141.      *
  142.      * @see HibernateEntityDao#remove(Object)
  143.      */
  144.     public void removeUndeleteable(Object entity);
  145.     
  146.     /**
  147.      * 与数据库相关的校验,比如判断名字在数据库里有没有重复, 在保存时被调用,在子类重载.
  148.      *
  149.      * @see #save(Object)
  150.      */
  151.     public void onValid(T entity);
  152.     
  153.     /**
  154.      * 根据Map中的条件的Criteria查询.
  155.      *
  156.      * @param map Map中仅包含条件名与条件值,默认全部相同,可重载。
  157.      */
  158.     @SuppressWarnings("unchecked")
  159.     public List<T> find(Map map);
  160.     
  161.     /**
  162.      * 根据Map中的条件的Criteria查询.
  163.      *
  164.      * @param map Map中仅包含条件名与条件值,默认全部相同,可重载.
  165.      */
  166.     @SuppressWarnings("unchecked")
  167.     public List<T> find(Criteria criteria, Map map);
  168.     
  169.     /*******************************************************************************************/
  170.     
  171.     /**
  172.      * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
  173.      */
  174.     public T get(Class<T> entityClass, Serializable id);
  175.     
  176.     /**
  177.      * 获取全部对象.
  178.      */
  179.     public  List<T> getAll(Class<T> entityClass);
  180.     
  181.     /**
  182.      * 获取全部对象,带排序字段与升降序参数.
  183.      */
  184.     public  List<T> getAll(Class<T> entityClass, String orderBy, boolean isAsc);
  185.     
  186.     /**
  187.      * 保存对象.
  188.      */
  189.     public void save(Object o);
  190.     
  191.     /**
  192.      * 删除对象.
  193.      */
  194.     public void remove(Object o);
  195.     
  196.     public void flush();
  197.     
  198.     public void clear();
  199.     
  200.     /**
  201.      * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
  202.      * 留意可以连续设置,如下:
  203.      * <pre>
  204.      * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
  205.      * </pre>
  206.      * 调用方式如下:
  207.      * <pre>
  208.      *        dao.createQuery(hql)
  209.      *        dao.createQuery(hql,arg0);
  210.      *        dao.createQuery(hql,arg0,arg1);
  211.      *        dao.createQuery(hql,new Object[arg0,arg1,arg2])
  212.      * </pre>
  213.      *
  214.      * @param values 可变参数.
  215.      */
  216.     public Query createQuery(String hql, Object... values);
  217.     
  218.     /**
  219.      * 创建Criteria对象.
  220.      *
  221.      * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)}
  222.      */
  223.     public  Criteria createCriteria(Class<T> entityClass, Criterion... criterions);
  224.     
  225.     /**
  226.      * 创建Criteria对象,带排序字段与升降序字段.
  227.      *
  228.      * @see #createCriteria(Class,Criterion[])
  229.      */
  230.     public  Criteria createCriteria(Class<T> entityClass, String orderBy, boolean isAsc, Criterion... criterions);
  231.     
  232.     /**
  233.      * 根据hql查询,直接使用HibernateTemplate的find函数.
  234.      *
  235.      * @param values 可变参数,见{@link #createQuery(String,Object...)}
  236.      */
  237.     @SuppressWarnings("unchecked")
  238.     public List find(String hql, Object... values);
  239.     
  240.     /**
  241.      * 根据属性名和属性值查询对象.
  242.      *
  243.      * @return 符合条件的对象列表
  244.      */
  245.     public  List<T> findBy(Class<T> entityClass, String propertyName, Object value);
  246.     
  247.     /**
  248.      * 根据属性名和属性值查询对象,带排序参数.
  249.      */
  250.     public  List<T> findBy(Class<T> entityClass, String propertyName, Object value, String orderBy, boolean isAsc);
  251.     
  252.     /**
  253.      * 根据属性名和属性值查询唯一对象.
  254.      *
  255.      * @return 符合条件的唯一对象 or null if not found.
  256.      */
  257.     public  T findUniqueBy(Class<T> entityClass, String propertyName, Object value);
  258.     
  259.     /**
  260.      * 分页查询函数,使用hql.
  261.      *
  262.      * @param pageNo 页号,从1开始.
  263.      */
  264.     public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values);
  265.     
  266.     /**
  267.      * @author Scott.wanglei
  268.      * @since  2008-7-21
  269.      * @param hql 查询sql
  270.      * @param start 分页从哪一条数据开始
  271.      * @param pageSize 每一个页面的大小
  272.      * @param values 查询条件
  273.      * @return page对象
  274.      */
  275.     public Page dataQuery(String hql, int start, int pageSize, Object... values);
  276.     
  277.     /**
  278.      * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
  279.      *
  280.      * @param pageNo 页号,从1开始.
  281.      * @return 含总记录数和当前页数据的Page对象.
  282.      */
  283.     public Page pagedQuery(Criteria criteria, int pageNo, int pageSize);
  284.     
  285.     /**
  286.      * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
  287.      *
  288.      * @param pageNo 页号,从1开始.
  289.      * @return 含总记录数和当前页数据的Page对象.
  290.      */
  291.     @SuppressWarnings("unchecked")
  292.     public Page pagedQuery(Class entityClass, int pageNo, int pageSize, Criterion... criterions);
  293.     
  294.     /**
  295.      * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
  296.      *
  297.      * @param pageNo 页号,从1开始.
  298.      * @return 含总记录数和当前页数据的Page对象.
  299.      */
  300.     @SuppressWarnings("unchecked")
  301.     public Page pagedQuery(Class entityClass, int pageNo, int pageSize, String orderBy, boolean isAsc,
  302.                Criterion... criterions);
  303.     
  304.     /**
  305.      * 判断对象某些属性的值在数据库中是否唯一.
  306.      *
  307.      * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  308.      */
  309.     public  boolean isUnique(Class<T> entityClass, Object entity, String uniquePropertyNames);
  310.     
  311.     /**
  312.      * 取得对象的主键值,辅助函数.
  313.      */
  314.     @SuppressWarnings("unchecked")
  315.     public Serializable getId(Class entityClass, Object entity) throws NoSuchMethodException, IllegalAccessException,
  316.     InvocationTargetException ;
  317.     
  318.     /**
  319.      * 取得对象的主键名,辅助函数.
  320.      */
  321.     @SuppressWarnings("unchecked")
  322.     public String getIdName(Class clazz);
  323. }
BaseDao.java
  1. /**
  2.  * 
  3.  */
  4. package com.demonstration.hibernate.basedao;
  5. import java.io.Serializable;
  6. import java.lang.reflect.InvocationTargetException;
  7. import java.util.List;
  8. import java.util.Map;
  9. import org.hibernate.Criteria;
  10. import org.hibernate.Query;
  11. import org.hibernate.criterion.Criterion;
  12. import com.demonstration.hibernate.dao.HibernateEntityDao;
  13. import com.demonstration.hibernate.dao.HibernateGenericDao;
  14. import com.demonstration.hibernate.dao.extend.HibernateEntityExtendDao;
  15. import com.demonstration.hibernate.dao.extend.IUndeleteableEntityOperation;
  16. import com.demonstration.hibernate.dao.support.Page;
  17. /**
  18.  * @author 
  19.  *
  20.  * IBaseDao的实现类通过spring注入HibernateEntityDao和HibernateEntityExtendDao来实现
  21.  */
  22. public class BaseDao<T> implements IBaseDao<T> {
  23.     protected Class<T> entityClass;// DAO所管理的Entity类型.
  24.     private HibernateEntityDao<T> hedao;
  25.     private HibernateEntityExtendDao<T> hexdao;
  26.     
  27.     
  28.     public void setHedao(HibernateEntityDao<T> hedao) {
  29.         hedao.setEntityClass(entityClass);
  30.         this.hedao=hedao;
  31.     }
  32.     public void setHexdao(HibernateEntityExtendDao<T> hexdao) {
  33.         hexdao.setEntityClass(entityClass);
  34.         this.hexdao=hexdao;
  35.     }
  36.     
  37.     /**
  38.      *让spring提供构造函数注入
  39.      */
  40.     public BaseDao(Class<T> type) {
  41.         this.entityClass = type;
  42.     }
  43.     
  44.     public BaseDao(){}
  45.     /**
  46.      * 根据ID获取对象.
  47.      * 
  48.      * @see HibernateGenericDao#getId(Class,Object)
  49.      */
  50.     public T get(Serializable id) {
  51.         return hedao.get(id);
  52.     }
  53.     /**
  54.      * 获取全部对象
  55.      * 
  56.      * @see HibernateGenericDao#getAll(Class)
  57.      */
  58.     public List<T> getAll() {
  59.         return hedao.getAll();
  60.     }
  61.     /**
  62.      * 获取全部对象,带排序参数.
  63.      * 
  64.      * @see HibernateGenericDao#getAll(Class,String,boolean)
  65.      */
  66.     public List<T> getAll(String orderBy, boolean isAsc) {
  67.         return hedao.getAll(orderBy, isAsc);
  68.     }
  69.     /**
  70.      * 根据ID移除对象.
  71.      * 
  72.      * @see HibernateGenericDao#removeById(Class,Serializable)
  73.      */
  74.     public void removeById(Serializable id) {
  75.         hedao.removeById(id);
  76.     }
  77.     /**
  78.      * 取得Entity的Criteria.
  79.      * 
  80.      * @see HibernateGenericDao#createCriteria(Class,Criterion[])
  81.      */
  82.     public Criteria createCriteria(Criterion... criterions) {
  83.         return hedao.createCriteria(criterions);
  84.     }
  85.     /**
  86.      * 取得Entity的Criteria,带排序参数.
  87.      * 
  88.      * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[])
  89.      */
  90.     public Criteria createCriteria(String orderBy, boolean isAsc,
  91.             Criterion... criterions) {
  92.         return hedao.createCriteria(orderBy, isAsc, criterions);
  93.     }
  94.     /**
  95.      * 根据属性名和属性值查询对象.
  96.      * 
  97.      * @return 符合条件的对象列表
  98.      * @see HibernateGenericDao#findBy(Class,String,Object)
  99.      */
  100.     public List<T> findBy(String propertyName, Object value) {
  101.         return hedao.findBy(propertyName, value);
  102.     }
  103.     /**
  104.      * 根据属性名和属性值查询对象,带排序参数.
  105.      * 
  106.      * @return 符合条件的对象列表
  107.      * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean)
  108.      */
  109.     public List<T> findBy(String propertyName, Object value, String orderBy,
  110.             boolean isAsc) {
  111.         return hedao.findBy(propertyName, value, orderBy, isAsc);
  112.     }
  113.     /**
  114.      * 根据属性名和属性值查询单个对象.
  115.      * 
  116.      * @return 符合条件的唯一对象 or null
  117.      * @see HibernateGenericDao#findUniqueBy(Class,String,Object)
  118.      */
  119.     public T findUniqueBy(String propertyName, Object value) {
  120.         return hedao.findUniqueBy(propertyName, value);
  121.     }
  122.     /**
  123.      * 判断对象某些属性的值在数据库中唯一.
  124.      * 
  125.      * @param uniquePropertyNames
  126.      *            在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  127.      * @see HibernateGenericDao#isUnique(Class,Object,String)
  128.      */
  129.     public boolean isUnique(Object entity, String uniquePropertyNames) {
  130.         return hedao.isUnique(entity, uniquePropertyNames);
  131.     }
  132.     /**
  133.      * 消除与 Hibernate Session 的关联
  134.      * 
  135.      * @param entity
  136.      */
  137.     public void evit(Object entity) {
  138.         hedao.evit(entity);
  139.     }
  140.     /**
  141.      * 取得所有状态为有效的对象.
  142.      *
  143.      * @see IUndeleteableEntityOperation#getAllValid()
  144.      */
  145.     public List<T> getAllValid() {
  146.         return hexdao.getAllValid();
  147.     }
  148.     /**
  149.      * 获取过滤已删除对象的hql条件语句.
  150.      *
  151.      * @see IUndeleteableEntityOperation#getUnDeletableHQL()
  152.      */
  153.     public String getUnDeletableHQL() {
  154.         return hexdao.getUnDeletableHQL();
  155.     }
  156.     /**
  157.      * 获取过滤已删除对象的Criterion条件语句.
  158.      *
  159.      * @see UndeleteableEntityOperation#
  160.      */
  161.     public Criterion getUnDeletableCriterion() {
  162.         return hexdao.getUnDeletableCriterion();
  163.     }
  164.     /**
  165.      * 重载保存函数,在保存前先调用onValid(T),进行书名不重复等数据库相关的校验.
  166.      *
  167.      * @see #onValid(Object)
  168.      * @see HibernateEntityDao#save(Object)
  169.      */
  170.     public void saveOnValid(Object entity) {
  171.          hexdao.save(entity);
  172.     }
  173.     /**
  174.      * 删除对象,如果是Undeleteable的entity,设置对象的状态而不是直接删除.
  175.      *
  176.      * @see HibernateEntityDao#remove(Object)
  177.      */
  178.     public void removeUndeleteable(Object entity) {
  179.            hexdao.remove(entity);
  180.     }
  181.     /**
  182.      * 与数据库相关的校验,比如判断名字在数据库里有没有重复, 在保存时被调用,在此可重写.
  183.      *
  184.      * @see #save(Object)
  185.      */
  186.     public void onValid(T entity) {
  187.            
  188.     }
  189.     /**
  190.      * 根据Map中的条件的Criteria查询.
  191.      *
  192.      * @param map Map中仅包含条件名与条件值,默认全部相同,可重载。
  193.      */
  194.     @SuppressWarnings("unchecked")
  195.     public List<T> find(Map map) {
  196.         return hexdao.find(map);
  197.     }
  198.     /**
  199.      * 根据Map中的条件的Criteria查询.
  200.      *
  201.      * @param map Map中仅包含条件名与条件值,默认全部相同,可重载.
  202.      */
  203.     @SuppressWarnings("unchecked")
  204.     public List<T> find(Criteria criteria, Map map) {
  205.         return hexdao.find(criteria, map);
  206.     }
  207.     /**
  208.      * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
  209.      */
  210.     public T get(Class<T> entityClass, Serializable id) {
  211.         return hedao.get(entityClass, id);
  212.     }
  213.     /**
  214.      * 获取全部对象.
  215.      */
  216.     public List<T> getAll(Class<T> entityClass) {
  217.         return hedao.getAll(entityClass);
  218.     }
  219.     /**
  220.      * 获取全部对象,带排序字段与升降序参数.
  221.      */
  222.     public List<T> getAll(Class<T> entityClass, String orderBy, boolean isAsc) {    
  223.         return hedao.getAll(entityClass, orderBy, isAsc);
  224.     }
  225.     /**
  226.      * 保存对象.
  227.      */
  228.     public void save(Object o) {
  229.           hedao.save(o);
  230.     }
  231.     /**
  232.      * 删除对象.
  233.      */
  234.     public void remove(Object o) {
  235.          hedao.remove(o);
  236.     }
  237.     
  238.     public void flush(){
  239.         hedao.flush();
  240.     }
  241.     
  242.     public void clear(){
  243.         hedao.clear();
  244.     }
  245.     /**
  246.      * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
  247.      * 留意可以连续设置,如下:
  248.      * <pre>
  249.      * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
  250.      * </pre>
  251.      * 调用方式如下:
  252.      * <pre>
  253.      *        dao.createQuery(hql)
  254.      *        dao.createQuery(hql,arg0);
  255.      *        dao.createQuery(hql,arg0,arg1);
  256.      *        dao.createQuery(hql,new Object[arg0,arg1,arg2])
  257.      * </pre>
  258.      *
  259.      * @param values 可变参数.
  260.      */
  261.     public Query createQuery(String hql, Object... values) {
  262.         
  263.         return hedao.createQuery(hql, values);
  264.     }
  265.     /**
  266.      * 创建Criteria对象.
  267.      *
  268.      * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)}
  269.      */
  270.     public Criteria createCriteria(Class<T> entityClass,
  271.             Criterion... criterions) {
  272.         
  273.         return hedao.createCriteria(entityClass, criterions);
  274.     }
  275.     /**
  276.      * 创建Criteria对象,带排序字段与升降序字段.
  277.      *
  278.      * @see #createCriteria(Class,Criterion[])
  279.      */
  280.     public Criteria createCriteria(Class<T> entityClass, String orderBy,
  281.             boolean isAsc, Criterion... criterions) {
  282.         return hedao.createCriteria(entityClass, orderBy, isAsc, criterions);
  283.     }
  284.     /**
  285.      * 根据hql查询,直接使用HibernateTemplate的find函数.
  286.      *
  287.      * @param values 可变参数,见{@link #createQuery(String,Object...)}
  288.      */
  289.     @SuppressWarnings("unchecked")
  290.     public List find(String hql, Object... values) {
  291.         return hedao.find(hql, values);
  292.     }
  293.     /**
  294.      * 根据属性名和属性值查询对象.
  295.      *
  296.      * @return 符合条件的对象列表
  297.      */
  298.     public  List<T> findBy(Class<T> entityClass, String propertyName,
  299.             Object value) {
  300.         
  301.         return hedao.findBy(entityClass, propertyName, value);
  302.     }
  303.     /**
  304.      * 根据属性名和属性值查询对象,带排序参数.
  305.      */
  306.     public List<T> findBy(Class<T> entityClass, String propertyName,
  307.             Object value, String orderBy, boolean isAsc) {
  308.         return hedao.findBy(entityClass, propertyName, value, orderBy, isAsc);
  309.     }
  310.     /**
  311.      * 根据属性名和属性值查询唯一对象.
  312.      *
  313.      * @return 符合条件的唯一对象 or null if not found.
  314.      */
  315.     public T findUniqueBy(Class<T> entityClass, String propertyName,
  316.             Object value) {
  317.         return hedao.findUniqueBy(propertyName, value);
  318.     }
  319.     /**
  320.      * 分页查询函数,使用hql.
  321.      *
  322.      * @param pageNo 页号,从1开始.
  323.      */
  324.     public Page pagedQuery(String hql, int pageNo, int pageSize,
  325.             Object... values) {
  326.         return hedao.pagedQuery(hql, pageNo, pageSize, values);
  327.     }
  328.     /**
  329.      * @author Scott.wanglei
  330.      * @since  2008-7-21
  331.      * @param hql 查询sql
  332.      * @param start 分页从哪一条数据开始
  333.      * @param pageSize 每一个页面的大小
  334.      * @param values 查询条件
  335.      * @return page对象
  336.      */
  337.     public Page dataQuery(String hql, int start, int pageSize, Object... values) {
  338.         return hedao.dataQuery(hql, start, pageSize, values);
  339.     }
  340.     /**
  341.      * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
  342.      *
  343.      * @param pageNo 页号,从1开始.
  344.      * @return 含总记录数和当前页数据的Page对象.
  345.      */
  346.     public Page pagedQuery(Criteria criteria, int pageNo, int pageSize) {
  347.         return hedao.pagedQuery(criteria, pageNo, pageSize);
  348.     }
  349.     
  350.     /**
  351.      * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
  352.      *
  353.      * @param pageNo 页号,从1开始.
  354.      * @return 含总记录数和当前页数据的Page对象.
  355.      */
  356.     @SuppressWarnings("unchecked")
  357.     public Page pagedQuery(Class entityClass, int pageNo, int pageSize,
  358.             Criterion... criterions) {
  359.         return hedao.pagedQuery(entityClass, pageNo, pageSize, criterions);
  360.     }
  361.     @SuppressWarnings("unchecked")
  362.     public Page pagedQuery(Class entityClass, int pageNo, int pageSize,
  363.             String orderBy, boolean isAsc, Criterion... criterions) {
  364.         return hedao.pagedQuery(entityClass, pageNo, pageSize, orderBy, isAsc, criterions);
  365.     }
  366.     /**
  367.      * 判断对象某些属性的值在数据库中是否唯一.
  368.      *
  369.      * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
  370.      */
  371.     public  boolean isUnique(Class<T> entityClass, Object entity,
  372.             String uniquePropertyNames) {
  373.         return hedao.isUnique(entity, uniquePropertyNames);
  374.     }
  375.     /**
  376.      * 取得对象的主键值,辅助函数.
  377.      */
  378.     @SuppressWarnings("unchecked")
  379.     public Serializable getId(Class entityClass, Object entity)
  380.             throws NoSuchMethodException, IllegalAccessException,
  381.             InvocationTargetException {
  382.         return hedao.getId(entityClass, entity);
  383.     }
  384.     /**
  385.      * 取得对象的主键名,辅助函数.
  386.      */
  387.     @SuppressWarnings("unchecked")
  388.     public String getIdName(Class clazz) {
  389.         return hedao.getIdName(clazz);
  390.     }
  391. }
使用时候的xml配置:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.     <bean id="hedao"
  6.         class="com.demonstration.hibernate.dao.HibernateEntityDao" scope="prototype">
  7.         <property name="sessionFactory">
  8.             <ref bean="sessionFactory" />
  9.         </property>
  10.     </bean>
  11.     <bean id="hexdao"
  12.         class="com.demonstration.hibernate.dao.extend.HibernateEntityExtendDao" scope="prototype">
  13.         <property name="sessionFactory">
  14.             <ref bean="sessionFactory" />
  15.         </property>
  16.     </bean>
  17.     <!--使用泛型DAO作为抽象基类-->
  18.     <bean id="baseDao" class="com.demonstration.hibernate.basedao.BaseDao"
  19.         abstract="true" depends-on="hedao,hexdao">
  20.         <property name="hedao">
  21.             <ref bean="hedao" />
  22.         </property>
  23.         <property name="hexdao">
  24.             <ref bean="hexdao" />
  25.         </property>
  26.     </bean>
  27.     
  28.     <!--下面这个dao没有写任何java代码完全有spring搞定 -->
  29.     <!-- 配置实体类的DAO -->
  30.     <bean id="demoDao" parent="baseDao">
  31.         <constructor-arg>
  32.                          <!--根据这个生成某一个实体的dao -->
  33.             <value>com.demonstration.entityclass.Demodata</value>
  34.         </constructor-arg>
  35.     </bean>
  36. </beans>