基于hibernate的泛型Dao层设计
2015-01-19 18:40
267 查看
泛型是JDK1.5的一个新的特性,使用泛型机制编写的程序代码要比那些杂乱的使用Object变量,然后再进行强制类型转换的代码具有更好的安全性和可读性。如果你的系统运行在JDK1.5以上的版本上,建议多使用泛型来代替无休止的对象转换。
在软件设计中我们开始对系统进行三层甚至是多层架构了,目的是职责更加的明确,功能更加的分离。而常常使用的三层架构就是将表现层、业务逻辑层和持久层进行分离,每一层关注点不同,职能更加的清晰。所以DAO的设计模式现在已经被我们所接受,下面就介绍一下泛型DAO的设计和实现。
这次的DAO例子是基于接口的.很多工具,像Hibernate已经提供了数据库的便携访问,所以我们不是为持久层的轻便而设计接口.然而,
DAO接口在较为复杂的应用中更有意义,当有几个持久化服务被封装到一个持久层的时候,我想在很多情况下你应该直接使用Hibernate或者JPA,而使用外加的DAO层最好的理由是为了实现更高的抽象化(例如:定义方法名findAll(String
hql)而不是无数次地重复session.createQuery(...))
通用DAO接口:
packagecom.baiyyy.util.dao;
importjava.io.Serializable;
importjava.util.Collection;
importjava.util.Iterator;
importjava.util.List;
importorg.hibernate.Criteria;
importorg.hibernate.LockMode;
importorg.hibernate.criterion.Criterion;
importorg.hibernate.criterion.DetachedCriteria;
/**
*承有业务数据的基础访问接口
*<p>
*承有CRUD(创建,读取,修改和删陿)基本数据的操作在这个接口中都是独立的_并且承有的DAO都可以使用这些基本实玿
*
*@authoryongtree
*
*@date:2008-03-04
*/
publicinterfaceIBaseDAO<T,IDextendsSerializable>{
/***************************************************************************
*-------------------基本棿索㿁增加㿁修改㿁删除操使----------------------------*
**************************************************************************/
//--------findById()方法是鿚过get(IDid)得到实体对象-----------------------
/**
*通过ID来得到实体对豿
*
*@paramid
*实体对象的标识符
*@paramlock
*使用的锁模式
*@return该主键忼对应的实体对象
*/
publicTfindById(IDid,LockModelock);
/**
*通过ID来得到实体对豿
*
*@paramid
*@returnT
*/
publicTfindById(IDid);
/**
*通过ID来得到实体对豿(为兼容其他开发成员的原有程序,保留使甿)
*
*@paramc
*@paramid
*@returnT
*/
publicTfindById(Classc,IDid);
//-------------loadById()是调用hibernate的load方法------------
publicTloadById(IDid);
/**
*通过idload对象
*
*@paramid
*@paramlock
*@return
*/
publicTloadById(IDid,LockModelock);
/**
*获取全部的实使
*
*@return
*/
publicList<T>loadAll();
/**
*保存丿个实体对豿
*
*@paramentity
*/
publicTsaveEntity(Tentity);
/**
*更新丿个实体对豿
*
*@paramentity
*/
publicvoidupdateEntity(Tentity);
publicvoidupdateEntity(Tentity,LockModelock);
/**
*增加或更新集合中的全部实使
*
*@paramentities
*/
publicvoidsaveOrUpdateAll(Collection<T>entities);
/**
*删除丿个实使
*
*@paramentity
*@throwsException
*/
publicvoiddeleteEntity(Tentity);
publicvoiddeleteEntity(Tentity,LockModelock);
/**
*根据主键删除指定实体
*
*@paramid
*/
publicvoiddeleteEntityById(IDid);
publicvoiddeleteEntityById(IDid,LockModelock);
/**
*批量删除
*
*@paramentities
*/
publicvoiddeleteAll(Collection<T>entities);
/**
*通过合并的方式更新对豿
*
*@paramentity
*void
*/
publicvoidmerge(Tentity);
/***************************************************************************
*------------------------------使用HQL语句--------------------------------*
**************************************************************************/
/**
*使用HQL语句进行对象的查诿
*
*@paramhsql
*查询语句
*@return符合条件的对豿
*/
publicTgetEntity(Stringhsql);
/**
*使用HQL语句进行查询
*
*@paramhsql
*查询语句
*@return符合条件的对象集吿
*/
publicList<T>getEntities(Stringhsql);
/**
*使用带参数的HQL语句进行查询
*
*@paramhsql
*@paramobj
*@return
*/
publicList<T>getEntities(Stringhsql,Object[]values);
publicList<T>getEntities(Stringhql,intstart,intnumber);
publicList<T>getEntities(Stringhql,intstart,intnumber,
Object[]values);
/**
*使用命名的HQL语句棿索数捿
*
*@paramqueryName
*@return
*/
publicList<T>findByNamedQuery(StringqueryName);
/**
*使用带参数的命名HSQL语句棿索数捿
*
*@paramqueryName
*@paramvalues
*@return
*/
publicList<T>findByNamedQuery(StringqueryName,Object[]values);
/**
*使用带命名参数的命名HSQL语句棿索数捿
*
*@paramqueryName
*@paramparamNames
*@paramvalues
*@return
*/
publicList<T>findByNamedQuery(StringqueryName,String[]paramNames,
Object[]values);
/**
*使用HQL语句棿索数据,返回Iterator
*
*@paramqueryString
*@return
*/
publicIterator<T>iterate(StringqueryString);
/**
*使用带参数HSQL语句棿索数据,返回Iterator
*
*@paramqueryString
*@paramvalues
*@return
*/
publicIterator<T>iterate(StringqueryString,Object[]values);
/***************************************************************************
*-----------------------------Criteria动濁查诿----------------------------*
**************************************************************************/
/**
*创建与会话无关的棿索标准对豿
*/
publicDetachedCriteriacreateDetachedCriteria();
/**
*创建与会话绑定的棿索标准对豿
*
*@return
*/
publicCriteriacreateCriteria();
/**
*使用指定的检索标准检索数捿
*
*@paramcriteria
*@return
*/
publicList<T>findByCriteria(DetachedCriteriacriteria);
/**
*使用指定的检索标准检索数据,返回部分记录
*
*@paramcriteria
*@paramfirstResult
*@parammaxResults
*@return
*/
publicList<T>findByCriteria(DetachedCriteriacriteria,intfirstResult,
intmaxResults);
/**
*通过动濁查询条件进行查诿
*
*@paramcriterion
*@returnList<T>
*/
@SuppressWarnings("unchecked")
publicList<T>findByCriteria(Criterion...criterion);
/**
*使用指定的检索标准检索数据,返回指定范围的记彿
*
*@paramcriteria
*@return
*/
publicIntegergetRowCount(DetachedCriteriacriteria);
/**
*使用指定的检索标准检索数据,返回指定统计倿
*
*@paramcriteria
*@parampropertyName
*@paramStatName
*(max,min,avg,sum)
*@return
*/
publicObjectgetStatValue(DetachedCriteriacriteria,StringpropertyName,
StringStatName);
/**
*通过给定的一个对象,查找与其匹配的对象,表关联比较多时,用户可以自己根据霿要扩展㿿
*
*@paramentity
*@returnList<T>
*/
publicList<T>findByExample(Tentity);
/***************************************************************************
*-------------------------Others----------------------------------------*
**************************************************************************/
/**
*加锁指定的实使
*
*@paramentity
*@paramlockMode
*/
publicvoidlock(Tentity,LockModelockMode);
/**
*强制立即更新缓冲数据到数据库(否则仅在事务提交时才更新)
*/
publicvoidflush();
/**
*清空缓存
*
*void
*/
publicvoidclear();
/***************************************************************************
*--------------------------------相关知识炿--------------------------------*
*
*1、Session的load方法和get方法都是通过给定的ID从数据库中加载一个持久化的对象㿂但两个斿*
*法的区别在于:当数据库不存在于ID对应的记录时,load()方法抛出异常,迌get()方法返回null*
***************************************************************************/
}
设计完接口,我们就要实现我们创建的接口,我们如果使用Hibernate,那么就做一个hibernate的实现,如果使用JPA,那么就做一个JPA实现。以下采用hibernate进行实现。
通用HibernateDAO实现:
packagecom.baiyyy.util.dao;
/**
*@filename:BaseHibernateDAO.java
*/
importjava.io.Serializable;
importjava.util.Collection;
importjava.util.Iterator;
importjava.util.List;
importorg.hibernate.Criteria;
importorg.hibernate.LockMode;
importorg.hibernate.Query;
importorg.hibernate.Session;
importorg.hibernate.criterion.Criterion;
importorg.hibernate.criterion.DetachedCriteria;
importorg.hibernate.criterion.Example;
importorg.hibernate.criterion.MatchMode;
importorg.hibernate.criterion.Projections;
importcom.baiyyy.workflow.pojo.TWfPackage;
/**
*用Hibernate实现通用DAO接口
*
*@authoryongtree
*@date2008-3-10
*@param<T>
*@param<ID>
*/
publicclassBaseHibernateDAO<T,IDextendsSerializable>implements
IBaseDAO<T,ID>{
//保持实体对象类的类型
privateClass<T>persistentClass;
privateSessionsession;
/**
*构鿠方泿
*/
@SuppressWarnings("unchecked")
publicBaseHibernateDAO(){
//下面这种方式丿直有错误,不能得到真正的T.class,迌是Object.class
//this.persistentClass=GenericsUtils.getSuperClassGenricType(getClass());
//System.out.println(obj.getClass().getName());
}
@SuppressWarnings("unchecked")
publicBaseHibernateDAO(Classclazz){
this.persistentClass=clazz;
}
/**
*@paramsession
*thesessiontoset
*/
publicvoidsetSession(Sessionsession){
this.session=session;
}
/**
*得到当前线程的Session对象的实便
*
*@return
*/
protectedSessiongetSession(){
System.out.println("getsession");
returnHibernateUtil.getCurrentSession();
}
/**
*得到持久化对象的类型
*
*@return持久化类的类垿
*/
protectedClass<T>getPersistentClass(){
returnpersistentClass;
}
@SuppressWarnings("unchecked")
publicTfindById(IDid,LockModelock){
//TODOAuto-generatedmethodstub
Tentity=(T)getSession().get(getPersistentClass(),id,lock);
if(entity!=null){
this.flush();
}
returnentity;
}
@SuppressWarnings("unchecked")
publicTfindById(Classc,IDid){
//TODOAuto-generatedmethodstub
Tentity;
entity=(T)getSession().get(c,id);
returnentity;
}
@SuppressWarnings("unchecked")
publicTfindById(IDid){
//TODOAuto-generatedmethodstub
Tentity=(T)getSession().get(getPersistentClass(),id);
returnentity;
}
@SuppressWarnings("unchecked")
publicTloadById(IDid){
//TODOAuto-generatedmethodstub
Tentity=(T)getSession().load(getPersistentClass(),id);
returnentity;
}
@SuppressWarnings("unchecked")
publicTloadById(Classc,IDid){
//TODOAuto-generatedmethodstub
Tentity=(T)getSession().load(c,id);
returnentity;
}
@SuppressWarnings("unchecked")
publicTloadById(IDid,LockModelock){
//TODOAuto-generatedmethodstub
Tentity=(T)getSession().load(getPersistentClass(),id,lock);
returnentity;
}
@SuppressWarnings("unchecked")
publicList<T>loadAll(){
List<T>list=getSession().createQuery(
"from"+getPersistentClass().getName()).list();
returnlist;
}
publicTsaveEntity(Tentity){
//TODOAuto-generatedmethodstub
getSession().save(entity);
this.flush();
returnentity;
}
publicvoidupdateEntity(Tentity){
//TODOAuto-generatedmethodstub
getSession().saveOrUpdate(entity);
this.flush();
}
/**
*该实现类暂时没有实现更新加锁的操使
*/
publicvoidupdateEntity(Tentity,LockModelock){
//TODOAuto-generatedmethodstub
getSession().saveOrUpdate(entity);
this.flush();
}
publicvoidsaveOrUpdateAll(Collection<T>entities){
getSession().saveOrUpdate(entities);
this.flush();
}
publicvoiddeleteEntity(Tentity){
//TODOAuto-generatedmethodstub
getSession().delete(entity);
this.flush();
}
/**
*该实现没有实现加锁删除对象的操作,在spring的DAO实现中已经实玿
*/
publicvoiddeleteEntity(Tentity,LockModelock){
//TODOAuto-generatedmethodstub
getSession().delete(entity);
this.flush();
}
publicvoiddeleteEntityById(IDid){
this.deleteEntity(this.loadById(id));
this.flush();
}
//该实现没有实现加锁的删除,在spring的dao中已经实现了
publicvoiddeleteEntityById(IDid,LockModelock){
this.deleteEntity(this.loadById(id));
this.flush();
}
publicvoiddeleteAll(Collection<T>entities){
this.flush();
getSession().delete(entities);
}
publicvoidmerge(Tentity){
getSession().merge(entity);
this.flush();
}
@SuppressWarnings("unchecked")
publicTgetEntity(Stringhsql){
TuniqueResult=(T)getSession().createQuery(hsql).uniqueResult();
//TODOAuto-generatedmethodstub
returnuniqueResult;
}
@SuppressWarnings("unchecked")
publicList<T>getEntities(Stringhsql){
//TODOAuto-generatedmethodstub
Listlist=getSession().createQuery(hsql).list();
returnlist;
}
@SuppressWarnings("unchecked")
publicList<T>getEntities(Stringhql,intstart,intnumber,
Object[]values){
//TODOAuto-generatedmethodstub
Queryquery=getSession().createQuery(hql);
for(inti=0;i<values.length;i++){
query.setParameter(i,values[i]);
}
query.setFirstResult(start);
query.setMaxResults(number);
Listlist=query.list();
returnlist;
}
@SuppressWarnings("unchecked")
publicList<T>getEntities(Stringhql,intstart,intnumber){
//TODOAuto-generatedmethodstub
Queryquery=getSession().createQuery(hql);
query.setFirstResult(start);
query.setMaxResults(number);
Listlist=query.list();
returnlist;
}
@SuppressWarnings("unchecked")
publicList<T>getEntities(Stringhql,Object[]values){
//TODOAuto-generatedmethodstub
Queryquery=getSession().createQuery(hql);
for(inti=0;i<values.length;i++){
query.setParameter(i,values[i]);
}
returnquery.list();
}
@SuppressWarnings("unchecked")
publicList<T>findByNamedQuery(StringqueryName){
//TODOAuto-generatedmethodstub
returngetSession().getNamedQuery(queryName).list();
}
@SuppressWarnings("unchecked")
publicList<T>findByNamedQuery(StringqueryName,Object[]values){
//TODOAuto-generatedmethodstub
Queryquery=getSession().getNamedQuery(queryName);
for(inti=0;i<values.length;i++){
query.setParameter(i,values);
}
returnquery.list();
}
/**
*注意:该方法是鿚过设置参数来进行命名查询,承以在传参数时,一定要注意paramNames和values的长度,位置要一丿对应〿
*/
@SuppressWarnings("unchecked")
publicList<T>findByNamedQuery(StringqueryName,String[]paramNames,
Object[]values){
//TODOAuto-generatedmethodstub
Queryquery=getSession().getNamedQuery(queryName);
for(inti=0;i<paramNames.length;i++){
query.setParameter(paramNames[i],values[i]);
}
returnquery.list();
}
@SuppressWarnings("unchecked")
publicIterator<T>iterate(Stringhql){
//TODOAuto-generatedmethodstub
returngetSession().createQuery(hql).iterate();
}
@SuppressWarnings("unchecked")
publicIterator<T>iterate(Stringhql,Object[]values){
//TODOAuto-generatedmethodstub
Queryquery=getSession().createQuery(hql);
for(inti=0;i<values.length;i++){
query.setParameter(i,values[i]);
}
returnquery.iterate();
}
publicDetachedCriteriacreateDetachedCriteria(){
//TODOAuto-generatedmethodstub
returnDetachedCriteria.forClass(this.persistentClass);
}
publicCriteriacreateCriteria(){
//TODOAuto-generatedmethodstub
returnthis.createDetachedCriteria().getExecutableCriteria(
this.getSession());
}
/**
*该方法没有经过验证,不能保证正确,在spring的实现中已经实现亿
*/
@SuppressWarnings("unchecked")
publicList<T>findByCriteria(DetachedCriteriacriteria){
//TODOAuto-generatedmethodstub
returncriteria.getExecutableCriteria(this.getSession()).list();
}
@SuppressWarnings("unchecked")
publicList<T>findByCriteria(DetachedCriteriacriteria,intfirstResult,
intmaxResults){
//TODOAuto-generatedmethodstub
returncriteria.getExecutableCriteria(this.getSession())
.setFirstResult(firstResult).setMaxResults(maxResults).list();
}
/**
*动濁查诿
*
*@paramcriterion
*@return
*/
public@SuppressWarnings("unchecked")
List<T>findByCriteria(Criterion...criterion){
Criteriacrit=getSession().createCriteria(getPersistentClass());
for(Criterionc:criterion){
if(c!=null){
crit.add(c);
}
}
Listlist=crit.list();
returnlist;
}
@SuppressWarnings("unchecked")
publicIntegergetRowCount(DetachedCriteriacriteria){
//TODOAuto-generatedmethodstub
criteria.setProjection(Projections.rowCount());
Listlist=this.findByCriteria(criteria,0,1);
return(Integer)list.get(0);
}
@SuppressWarnings("unchecked")
publicObjectgetStatValue(DetachedCriteriacriteria,StringpropertyName,
StringStatName){
//TODOAuto-generatedmethodstub
if(StatName.toLowerCase().equals("max"))
criteria.setProjection(Projections.max(propertyName));
elseif(StatName.toLowerCase().equals("min"))
criteria.setProjection(Projections.min(propertyName));
elseif(StatName.toLowerCase().equals("avg"))
criteria.setProjection(Projections.avg(propertyName));
elseif(StatName.toLowerCase().equals("sum"))
criteria.setProjection(Projections.sum(propertyName));
else
returnnull;
Listlist=this.findByCriteria(criteria,0,1);
returnlist.get(0);
}
@SuppressWarnings("unchecked")
publicList<T>findByExample(TexampleInstance){
//TODOAuto-generatedmethodstub
Criteriacrit=getSession().createCriteria(getPersistentClass());
Exampleexample=Example.create(exampleInstance);
example.ignoreCase().enableLike(MatchMode.ANYWHERE);//忽略大小写,并进行模糊比辿
example.excludeZeroes();//对于属濧中有数字类型的,如果exampleInstance的属性忼为0,就把它添加到查询中
crit.add(example);
returncrit.list();
}
publicvoidlock(Tentity,LockModelockMode){
//TODOAuto-generatedmethodstub
getSession().lock(entity,lockMode);
}
publicvoidflush(){
//TODOAuto-generatedmethodstub
getSession().flush();
}
publicvoidclear(){
//TODOAuto-generatedmethodstub
getSession().clear();
}
}
到现在为止,Hibernate通用DAO已经建立完成,作为一个通用的工具类,我们希望每个实体DAO都能继承这个DAO。继续发扬接口编程,每一个持久化实体类我们都建立一个接口,并且让这些接口都继承IBaseDAO。
//自定义该实体的接口
//实现自定义的方法
注:在BaseHibernateDAO的无参数构造函数中
publicBaseHibernateDAO(){
//下面这种方式一直有错误,不能得到真正的T.class,迌是Object.class
//this.persistentClass=GenericsUtils.getSuperClassGenricType(getClass());
}
这种方式的写法在springside中使用过,但是自己调试始终有错误,始终无法得到T.class,得到的只是Oject.class,不知道怎么解决,还请高人指点。
以下是我的替代方法,可能不是太好。构建一个带有Class参数的构造函数,让每个DAO硬性传入class。
publicBaseHibernateDAO(Classclazz){
this.persistentClass=clazz;
}
然后在子类DAO的构造参数中向父类传递一个class,因为一个DAO对应着一个实体,所以传入一个实体的class也是没有什么不可以的。
补充GenericsUtils.java:
在实际的项目中,我们常常忽略了业务逻辑层,我们有人喜欢将大部分的逻辑放在表现层的JavaBean中,也有人喜欢在DAO中编写自己的业务逻辑,虽然功能都能实现,但是职责不明,让我们面对这些杂乱无章的代码,我们无所适从。泛型DAO的设计我感觉很大程度上可以强制程序员不要在DAO中书写自己的逻辑代码,也让我们慢慢的建立自己业务逻辑层(在EJB,spring这样的框架没有引入的情况下)。
当然为了系统的可扩展性、可移植性和系统的松耦合,我们可以采用DAO工厂模式和反射机制来架构我们的系统,由于篇幅有限,这里就不做介绍了。这部分内容我将在以后的时间里进行整理并发布在我的csdn博客和javaeye博客上。
在软件设计中我们开始对系统进行三层甚至是多层架构了,目的是职责更加的明确,功能更加的分离。而常常使用的三层架构就是将表现层、业务逻辑层和持久层进行分离,每一层关注点不同,职能更加的清晰。所以DAO的设计模式现在已经被我们所接受,下面就介绍一下泛型DAO的设计和实现。
这次的DAO例子是基于接口的.很多工具,像Hibernate已经提供了数据库的便携访问,所以我们不是为持久层的轻便而设计接口.然而,
DAO接口在较为复杂的应用中更有意义,当有几个持久化服务被封装到一个持久层的时候,我想在很多情况下你应该直接使用Hibernate或者JPA,而使用外加的DAO层最好的理由是为了实现更高的抽象化(例如:定义方法名findAll(String
hql)而不是无数次地重复session.createQuery(...))
通用DAO接口:
packagecom.baiyyy.util.dao;
importjava.io.Serializable;
importjava.util.Collection;
importjava.util.Iterator;
importjava.util.List;
importorg.hibernate.Criteria;
importorg.hibernate.LockMode;
importorg.hibernate.criterion.Criterion;
importorg.hibernate.criterion.DetachedCriteria;
/**
*承有业务数据的基础访问接口
*<p>
*承有CRUD(创建,读取,修改和删陿)基本数据的操作在这个接口中都是独立的_并且承有的DAO都可以使用这些基本实玿
*
*@author
*
*@date:2008-03-04
*/
publicinterfaceIBaseDAO<T,IDextendsSerializable>{
/***************************************************************************
*-------------------基本棿索㿁增加㿁修改㿁删除操使----------------------------*
**************************************************************************/
//--------findById()方法是鿚过get(IDid)得到实体对象-----------------------
/**
*通过ID来得到实体对豿
*
*@paramid
*实体对象的标识符
*@paramlock
*使用的锁模式
*@return该主键忼对应的实体对象
*/
publicTfindById(IDid,LockModelock);
/**
*通过ID来得到实体对豿
*
*@paramid
*@returnT
*/
publicTfindById(IDid);
/**
*通过ID来得到实体对豿(为兼容其他开发成员的原有程序,保留使甿)
*
*@paramc
*@paramid
*@returnT
*/
publicTfindById(Classc,IDid);
//-------------loadById()是调用hibernate的load方法------------
publicTloadById(IDid);
/**
*通过idload对象
*
*@paramid
*@paramlock
*@return
*/
publicTloadById(IDid,LockModelock);
/**
*获取全部的实使
*
*@return
*/
publicList<T>loadAll();
/**
*保存丿个实体对豿
*
*@paramentity
*/
publicTsaveEntity(Tentity);
/**
*更新丿个实体对豿
*
*@paramentity
*/
publicvoidupdateEntity(Tentity);
publicvoidupdateEntity(Tentity,LockModelock);
/**
*增加或更新集合中的全部实使
*
*@paramentities
*/
publicvoidsaveOrUpdateAll(Collection<T>entities);
/**
*删除丿个实使
*
*@paramentity
*@throwsException
*/
publicvoiddeleteEntity(Tentity);
publicvoiddeleteEntity(Tentity,LockModelock);
/**
*根据主键删除指定实体
*
*@paramid
*/
publicvoiddeleteEntityById(IDid);
publicvoiddeleteEntityById(IDid,LockModelock);
/**
*批量删除
*
*@paramentities
*/
publicvoiddeleteAll(Collection<T>entities);
/**
*通过合并的方式更新对豿
*
*@paramentity
*void
*/
publicvoidmerge(Tentity);
/***************************************************************************
*------------------------------使用HQL语句--------------------------------*
**************************************************************************/
/**
*使用HQL语句进行对象的查诿
*
*@paramhsql
*查询语句
*@return符合条件的对豿
*/
publicTgetEntity(Stringhsql);
/**
*使用HQL语句进行查询
*
*@paramhsql
*查询语句
*@return符合条件的对象集吿
*/
publicList<T>getEntities(Stringhsql);
/**
*使用带参数的HQL语句进行查询
*
*@paramhsql
*@paramobj
*@return
*/
publicList<T>getEntities(Stringhsql,Object[]values);
publicList<T>getEntities(Stringhql,intstart,intnumber);
publicList<T>getEntities(Stringhql,intstart,intnumber,
Object[]values);
/**
*使用命名的HQL语句棿索数捿
*
*@paramqueryName
*@return
*/
publicList<T>findByNamedQuery(StringqueryName);
/**
*使用带参数的命名HSQL语句棿索数捿
*
*@paramqueryName
*@paramvalues
*@return
*/
publicList<T>findByNamedQuery(StringqueryName,Object[]values);
/**
*使用带命名参数的命名HSQL语句棿索数捿
*
*@paramqueryName
*@paramparamNames
*@paramvalues
*@return
*/
publicList<T>findByNamedQuery(StringqueryName,String[]paramNames,
Object[]values);
/**
*使用HQL语句棿索数据,返回Iterator
*
*@paramqueryString
*@return
*/
publicIterator<T>iterate(StringqueryString);
/**
*使用带参数HSQL语句棿索数据,返回Iterator
*
*@paramqueryString
*@paramvalues
*@return
*/
publicIterator<T>iterate(StringqueryString,Object[]values);
/***************************************************************************
*-----------------------------Criteria动濁查诿----------------------------*
**************************************************************************/
/**
*创建与会话无关的棿索标准对豿
*/
publicDetachedCriteriacreateDetachedCriteria();
/**
*创建与会话绑定的棿索标准对豿
*
*@return
*/
publicCriteriacreateCriteria();
/**
*使用指定的检索标准检索数捿
*
*@paramcriteria
*@return
*/
publicList<T>findByCriteria(DetachedCriteriacriteria);
/**
*使用指定的检索标准检索数据,返回部分记录
*
*@paramcriteria
*@paramfirstResult
*@parammaxResults
*@return
*/
publicList<T>findByCriteria(DetachedCriteriacriteria,intfirstResult,
intmaxResults);
/**
*通过动濁查询条件进行查诿
*
*@paramcriterion
*@returnList<T>
*/
@SuppressWarnings("unchecked")
publicList<T>findByCriteria(Criterion...criterion);
/**
*使用指定的检索标准检索数据,返回指定范围的记彿
*
*@paramcriteria
*@return
*/
publicIntegergetRowCount(DetachedCriteriacriteria);
/**
*使用指定的检索标准检索数据,返回指定统计倿
*
*@paramcriteria
*@parampropertyName
*@paramStatName
*(max,min,avg,sum)
*@return
*/
publicObjectgetStatValue(DetachedCriteriacriteria,StringpropertyName,
StringStatName);
/**
*通过给定的一个对象,查找与其匹配的对象,表关联比较多时,用户可以自己根据霿要扩展㿿
*
*@paramentity
*@returnList<T>
*/
publicList<T>findByExample(Tentity);
/***************************************************************************
*-------------------------Others----------------------------------------*
**************************************************************************/
/**
*加锁指定的实使
*
*@paramentity
*@paramlockMode
*/
publicvoidlock(Tentity,LockModelockMode);
/**
*强制立即更新缓冲数据到数据库(否则仅在事务提交时才更新)
*/
publicvoidflush();
/**
*清空缓存
*
*void
*/
publicvoidclear();
/***************************************************************************
*--------------------------------相关知识炿--------------------------------*
*
*1、Session的load方法和get方法都是通过给定的ID从数据库中加载一个持久化的对象㿂但两个斿*
*法的区别在于:当数据库不存在于ID对应的记录时,load()方法抛出异常,迌get()方法返回null*
***************************************************************************/
}
设计完接口,我们就要实现我们创建的接口,我们如果使用Hibernate,那么就做一个hibernate的实现,如果使用JPA,那么就做一个JPA实现。以下采用hibernate进行实现。
通用HibernateDAO实现:
packagecom.baiyyy.util.dao;
/**
*@filename:BaseHibernateDAO.java
*/
importjava.io.Serializable;
importjava.util.Collection;
importjava.util.Iterator;
importjava.util.List;
importorg.hibernate.Criteria;
importorg.hibernate.LockMode;
importorg.hibernate.Query;
importorg.hibernate.Session;
importorg.hibernate.criterion.Criterion;
importorg.hibernate.criterion.DetachedCriteria;
importorg.hibernate.criterion.Example;
importorg.hibernate.criterion.MatchMode;
importorg.hibernate.criterion.Projections;
importcom.baiyyy.workflow.pojo.TWfPackage;
/**
*用Hibernate实现通用DAO接口
*
*@author
*@date2008-3-10
*@param<T>
*@param<ID>
*/
publicclassBaseHibernateDAO<T,IDextendsSerializable>implements
IBaseDAO<T,ID>{
//保持实体对象类的类型
privateClass<T>persistentClass;
privateSessionsession;
/**
*构鿠方泿
*/
@SuppressWarnings("unchecked")
publicBaseHibernateDAO(){
//下面这种方式丿直有错误,不能得到真正的T.class,迌是Object.class
//this.persistentClass=GenericsUtils.getSuperClassGenricType(getClass());
//System.out.println(obj.getClass().getName());
}
@SuppressWarnings("unchecked")
publicBaseHibernateDAO(Classclazz){
this.persistentClass=clazz;
}
/**
*@paramsession
*thesessiontoset
*/
publicvoidsetSession(Sessionsession){
this.session=session;
}
/**
*得到当前线程的Session对象的实便
*
*@return
*/
protectedSessiongetSession(){
System.out.println("getsession");
returnHibernateUtil.getCurrentSession();
}
/**
*得到持久化对象的类型
*
*@return持久化类的类垿
*/
protectedClass<T>getPersistentClass(){
returnpersistentClass;
}
@SuppressWarnings("unchecked")
publicTfindById(IDid,LockModelock){
//TODOAuto-generatedmethodstub
Tentity=(T)getSession().get(getPersistentClass(),id,lock);
if(entity!=null){
this.flush();
}
returnentity;
}
@SuppressWarnings("unchecked")
publicTfindById(Classc,IDid){
//TODOAuto-generatedmethodstub
Tentity;
entity=(T)getSession().get(c,id);
returnentity;
}
@SuppressWarnings("unchecked")
publicTfindById(IDid){
//TODOAuto-generatedmethodstub
Tentity=(T)getSession().get(getPersistentClass(),id);
returnentity;
}
@SuppressWarnings("unchecked")
publicTloadById(IDid){
//TODOAuto-generatedmethodstub
Tentity=(T)getSession().load(getPersistentClass(),id);
returnentity;
}
@SuppressWarnings("unchecked")
publicTloadById(Classc,IDid){
//TODOAuto-generatedmethodstub
Tentity=(T)getSession().load(c,id);
returnentity;
}
@SuppressWarnings("unchecked")
publicTloadById(IDid,LockModelock){
//TODOAuto-generatedmethodstub
Tentity=(T)getSession().load(getPersistentClass(),id,lock);
returnentity;
}
@SuppressWarnings("unchecked")
publicList<T>loadAll(){
List<T>list=getSession().createQuery(
"from"+getPersistentClass().getName()).list();
returnlist;
}
publicTsaveEntity(Tentity){
//TODOAuto-generatedmethodstub
getSession().save(entity);
this.flush();
returnentity;
}
publicvoidupdateEntity(Tentity){
//TODOAuto-generatedmethodstub
getSession().saveOrUpdate(entity);
this.flush();
}
/**
*该实现类暂时没有实现更新加锁的操使
*/
publicvoidupdateEntity(Tentity,LockModelock){
//TODOAuto-generatedmethodstub
getSession().saveOrUpdate(entity);
this.flush();
}
publicvoidsaveOrUpdateAll(Collection<T>entities){
getSession().saveOrUpdate(entities);
this.flush();
}
publicvoiddeleteEntity(Tentity){
//TODOAuto-generatedmethodstub
getSession().delete(entity);
this.flush();
}
/**
*该实现没有实现加锁删除对象的操作,在spring的DAO实现中已经实玿
*/
publicvoiddeleteEntity(Tentity,LockModelock){
//TODOAuto-generatedmethodstub
getSession().delete(entity);
this.flush();
}
publicvoiddeleteEntityById(IDid){
this.deleteEntity(this.loadById(id));
this.flush();
}
//该实现没有实现加锁的删除,在spring的dao中已经实现了
publicvoiddeleteEntityById(IDid,LockModelock){
this.deleteEntity(this.loadById(id));
this.flush();
}
publicvoiddeleteAll(Collection<T>entities){
this.flush();
getSession().delete(entities);
}
publicvoidmerge(Tentity){
getSession().merge(entity);
this.flush();
}
@SuppressWarnings("unchecked")
publicTgetEntity(Stringhsql){
TuniqueResult=(T)getSession().createQuery(hsql).uniqueResult();
//TODOAuto-generatedmethodstub
returnuniqueResult;
}
@SuppressWarnings("unchecked")
publicList<T>getEntities(Stringhsql){
//TODOAuto-generatedmethodstub
Listlist=getSession().createQuery(hsql).list();
returnlist;
}
@SuppressWarnings("unchecked")
publicList<T>getEntities(Stringhql,intstart,intnumber,
Object[]values){
//TODOAuto-generatedmethodstub
Queryquery=getSession().createQuery(hql);
for(inti=0;i<values.length;i++){
query.setParameter(i,values[i]);
}
query.setFirstResult(start);
query.setMaxResults(number);
Listlist=query.list();
returnlist;
}
@SuppressWarnings("unchecked")
publicList<T>getEntities(Stringhql,intstart,intnumber){
//TODOAuto-generatedmethodstub
Queryquery=getSession().createQuery(hql);
query.setFirstResult(start);
query.setMaxResults(number);
Listlist=query.list();
returnlist;
}
@SuppressWarnings("unchecked")
publicList<T>getEntities(Stringhql,Object[]values){
//TODOAuto-generatedmethodstub
Queryquery=getSession().createQuery(hql);
for(inti=0;i<values.length;i++){
query.setParameter(i,values[i]);
}
returnquery.list();
}
@SuppressWarnings("unchecked")
publicList<T>findByNamedQuery(StringqueryName){
//TODOAuto-generatedmethodstub
returngetSession().getNamedQuery(queryName).list();
}
@SuppressWarnings("unchecked")
publicList<T>findByNamedQuery(StringqueryName,Object[]values){
//TODOAuto-generatedmethodstub
Queryquery=getSession().getNamedQuery(queryName);
for(inti=0;i<values.length;i++){
query.setParameter(i,values);
}
returnquery.list();
}
/**
*注意:该方法是鿚过设置参数来进行命名查询,承以在传参数时,一定要注意paramNames和values的长度,位置要一丿对应〿
*/
@SuppressWarnings("unchecked")
publicList<T>findByNamedQuery(StringqueryName,String[]paramNames,
Object[]values){
//TODOAuto-generatedmethodstub
Queryquery=getSession().getNamedQuery(queryName);
for(inti=0;i<paramNames.length;i++){
query.setParameter(paramNames[i],values[i]);
}
returnquery.list();
}
@SuppressWarnings("unchecked")
publicIterator<T>iterate(Stringhql){
//TODOAuto-generatedmethodstub
returngetSession().createQuery(hql).iterate();
}
@SuppressWarnings("unchecked")
publicIterator<T>iterate(Stringhql,Object[]values){
//TODOAuto-generatedmethodstub
Queryquery=getSession().createQuery(hql);
for(inti=0;i<values.length;i++){
query.setParameter(i,values[i]);
}
returnquery.iterate();
}
publicDetachedCriteriacreateDetachedCriteria(){
//TODOAuto-generatedmethodstub
returnDetachedCriteria.forClass(this.persistentClass);
}
publicCriteriacreateCriteria(){
//TODOAuto-generatedmethodstub
returnthis.createDetachedCriteria().getExecutableCriteria(
this.getSession());
}
/**
*该方法没有经过验证,不能保证正确,在spring的实现中已经实现亿
*/
@SuppressWarnings("unchecked")
publicList<T>findByCriteria(DetachedCriteriacriteria){
//TODOAuto-generatedmethodstub
returncriteria.getExecutableCriteria(this.getSession()).list();
}
@SuppressWarnings("unchecked")
publicList<T>findByCriteria(DetachedCriteriacriteria,intfirstResult,
intmaxResults){
//TODOAuto-generatedmethodstub
returncriteria.getExecutableCriteria(this.getSession())
.setFirstResult(firstResult).setMaxResults(maxResults).list();
}
/**
*动濁查诿
*
*@paramcriterion
*@return
*/
public@SuppressWarnings("unchecked")
List<T>findByCriteria(Criterion...criterion){
Criteriacrit=getSession().createCriteria(getPersistentClass());
for(Criterionc:criterion){
if(c!=null){
crit.add(c);
}
}
Listlist=crit.list();
returnlist;
}
@SuppressWarnings("unchecked")
publicIntegergetRowCount(DetachedCriteriacriteria){
//TODOAuto-generatedmethodstub
criteria.setProjection(Projections.rowCount());
Listlist=this.findByCriteria(criteria,0,1);
return(Integer)list.get(0);
}
@SuppressWarnings("unchecked")
publicObjectgetStatValue(DetachedCriteriacriteria,StringpropertyName,
StringStatName){
//TODOAuto-generatedmethodstub
if(StatName.toLowerCase().equals("max"))
criteria.setProjection(Projections.max(propertyName));
elseif(StatName.toLowerCase().equals("min"))
criteria.setProjection(Projections.min(propertyName));
elseif(StatName.toLowerCase().equals("avg"))
criteria.setProjection(Projections.avg(propertyName));
elseif(StatName.toLowerCase().equals("sum"))
criteria.setProjection(Projections.sum(propertyName));
else
returnnull;
Listlist=this.findByCriteria(criteria,0,1);
returnlist.get(0);
}
@SuppressWarnings("unchecked")
publicList<T>findByExample(TexampleInstance){
//TODOAuto-generatedmethodstub
Criteriacrit=getSession().createCriteria(getPersistentClass());
Exampleexample=Example.create(exampleInstance);
example.ignoreCase().enableLike(MatchMode.ANYWHERE);//忽略大小写,并进行模糊比辿
example.excludeZeroes();//对于属濧中有数字类型的,如果exampleInstance的属性忼为0,就把它添加到查询中
crit.add(example);
returncrit.list();
}
publicvoidlock(Tentity,LockModelockMode){
//TODOAuto-generatedmethodstub
getSession().lock(entity,lockMode);
}
publicvoidflush(){
//TODOAuto-generatedmethodstub
getSession().flush();
}
publicvoidclear(){
//TODOAuto-generatedmethodstub
getSession().clear();
}
}
到现在为止,Hibernate通用DAO已经建立完成,作为一个通用的工具类,我们希望每个实体DAO都能继承这个DAO。继续发扬接口编程,每一个持久化实体类我们都建立一个接口,并且让这些接口都继承IBaseDAO。
ParticipantDAO
的写法:
publicinterface
ParticipantDAO
extends
IBaseDAO<TWfParticipants,Integer>{
//自定义该实体的接口
}
ParticipantDAO
实现类的写法:
publicclass
ParticipantDAOImpl
extends
BaseHibernateDAO<TWfParticipants,Integer>implements
ParticipantDAO{
publicParticipantDAOImpl(){
super(TWfParticipants.class);
}
//实现自定义的方法
}
注:在BaseHibernateDAO的无参数构造函数中
publicBaseHibernateDAO(){
//下面这种方式一直有错误,不能得到真正的T.class,迌是Object.class
//this.persistentClass=GenericsUtils.getSuperClassGenricType(getClass());
}
这种方式的写法在springside中使用过,但是自己调试始终有错误,始终无法得到T.class,得到的只是Oject.class,不知道怎么解决,还请高人指点。
以下是我的替代方法,可能不是太好。构建一个带有Class参数的构造函数,让每个DAO硬性传入class。
publicBaseHibernateDAO(Classclazz){
this.persistentClass=clazz;
}
然后在子类DAO的构造参数中向父类传递一个class,因为一个DAO对应着一个实体,所以传入一个实体的class也是没有什么不可以的。
public
ParticipantDAOImpl(){
super(TWfParticipants.class);
}
补充GenericsUtils.java:
publicclass
GenericsUtils{
privatestaticfinalLoglog=LogFactory.getLog(GenericsUtils.class);
privateGenericsUtils(){
}
/**
*
通过反射
,
获得定义
Class
时声明的父类的范型参数的类型
.
如
publicBookManagerextendsGenricManager
<Book>
*
*@paramclazz
*Theclasstointrospect
*@returnthefirstgenericdeclaration,or<code>Object.class</code>if
*cannotbedetermined
*/
publicstaticClassgetSuperClassGenricType(Classclazz){
returngetSuperClassGenricType(clazz,0);
}
/**
*
通过反射
,
获得定义
Class
时声明的父类的范型参数的类型
.
如
publicBookManagerextendsGenricManager
<Book>
*
*@paramclazz
*clazzTheclasstointrospect
*@paramindex
*theIndexofthegenericddeclaration,startfrom0.
*/
publicstaticClassgetSuperClassGenricType(Classclazz,intindex)
throwsIndexOutOfBoundsException{
TypegenType=clazz.getGenericSuperclass();
//TypegenType=clazz;
if(!(genTypeinstanceofParameterizedType)){
log.warn(clazz.getSimpleName()
+"'ssuperclassnotParameterizedType");
returnclazz;
}
Type[]params=((ParameterizedType)genType).getActualTypeArguments();
if(index>=params.length||index<0){
log.warn("Index:"+index+",Sizeof"+clazz.getSimpleName()
+"'sParameterizedType:"+params.length);
returnObject.class;
}
if(!(params[index]instanceofClass)){
log
.warn(clazz.getSimpleName()
+"notsettheactualclassonsuperclassgenericparameter");
returnObject.class;
}
return(Class)params[index];
}
}
在实际的项目中,我们常常忽略了业务逻辑层,我们有人喜欢将大部分的逻辑放在表现层的JavaBean中,也有人喜欢在DAO中编写自己的业务逻辑,虽然功能都能实现,但是职责不明,让我们面对这些杂乱无章的代码,我们无所适从。泛型DAO的设计我感觉很大程度上可以强制程序员不要在DAO中书写自己的逻辑代码,也让我们慢慢的建立自己业务逻辑层(在EJB,spring这样的框架没有引入的情况下)。
当然为了系统的可扩展性、可移植性和系统的松耦合,我们可以采用DAO工厂模式和反射机制来架构我们的系统,由于篇幅有限,这里就不做介绍了。这部分内容我将在以后的时间里进行整理并发布在我的csdn博客和javaeye博客上。
相关文章推荐
- 基于泛型DAO的Facade设计模式. - Hibernate - Java
- 基于Hibernate框架的泛型DAO层---SwiftDAO
- hibernate的dao层通用设计
- Hibernate泛型DAO设计
- 《C++ Primer》 对象、数组、基于对象设计、泛型设计
- 基于泛型的通用Dao接口和hibernate的实现
- 基于泛型的通用Dao接口和hibernate的实现
- 基于整合了struts 和hibernate 的j2ee 架构的用户权限管理系统的设计与实现
- hibernate基于泛型基础增删改查方法封装
- 基于泛型DAO的设计模式
- 基于hibernate的BaseDao及其实现类的设计
- 基于Spring的DAO层设计
- 基于Struts+Hibernate的Web项目权限设计(2)
- 基于hibernate的泛型Dao框架
- 基于Spring和hibernate的web项目分层设计
- 基于泛型的通用Dao接口hibernate实现
- 基于Spring的DAO层设计
- 基于Spring的DAO层设计
- SSH实例:基于HibernateDaoSupport的泛型Dao
- 基于Hibernate的对象关联关系设计时注意事项