一个好用的hibernate泛型dao

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

先看图:

一个好用的hibernate泛型dao  

一共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>

 

你可能感兴趣的:(Hibernate)