SpringSide 的 hibernate的封装
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, params),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、fatchsize、cache、cacheRegion等多个查询参数,所以spring宁愿返回已设置好查询参数的Query和Criteria,让大家继续剩下的参数设置,最后再执行list(),注意那个几个参数是可以连续设置的。如:
createQuery(hql, param).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 name);
2、HibernateEntityDao
所以userManger、productManager之类只管理一类对象的Manager类的基类,只需要在类定义处声明entity类型即可。
public class BookManager extends HibernateEntityDao<Book>{};
通过<Book> 的定义,避免了HibernateGenericDao类个方法中必有的Class entityClass参数。
如果需要操作其它的entity,比如BookManager需要处理Category(图书目录),可以注入CategoryManager,无需担心事务的问题,javaEE默认的事务模型已经能很好的处理。
如果没有对应的CategoryManager,或各种原因不想注入的话,可以使用BookManager继承的HibernateGenericDao自带entityClass参数的函数来操作Category的CRUD,如Category category = this.get(Category.class, 1);
3、HibernateExtendsDao
此类演示SpringSide所做的一些扩展,大家可以根据自己的需求进行修改和扩展
1>、支持对象不能被直接删除,只能标示状态为无效列。
接口:UndeleteableEntityOperation,定义了支持此功能必须要实现的函数。
可以有接口(UndeleteableEntity) 和 annotation(@undeleteable) 两种形式来定义无效列,annotation列形式还可以定义标示对象已删除的状态的名称,用接口则必须实现setStatus()接口,在里面操作实际的状态属性。
两种方式的异同可见:侵入、非侵入 Interface vs Annotation
2>、重装save(); 在保存前先调用 onValid() 函数。
3>、增加find(Map map) 接口;
默认查找所有与map中条件全部相同的entity。
条件的比较运算符默认相同,用户也可以为属性名加上 like_, largerthen_这样的前缀,则使用相应的运算符做比较。