无奈,寻找好的解决方法,把我现在擦屁股的现场记录下来。
我用GenericHibernateDAO,慢慢积累下来的,有这几个DetachedCriteria的方法:
public
List findByDetachedCriteriaByPage(
final
DetachedCriteria detachedCriteria,
final
int
pagesize,
final
int
pageno) {
return
getHibernateTemplate()
.findByCriteria(detachedCriteria, pagesize
*
pageno, pagesize);
}
int
getCountByDetachedCriteria(
final
DetachedCriteria detachedCriteria) {
Integer count
=
(Integer) getHibernateTemplate().execute(
new
HibernateCallback() {
public
Object doInHibernate(Session session)
throws
HibernateException {
Criteria criteria
=
detachedCriteria.getExecutableCriteria(session);
return
criteria.setProjection(Projections.rowCount())
.uniqueResult();
}
},
true
);
detachedCriteria.setProjection(
null
);
return
count.intValue();
}
这是一对方法,经常一起用,一开始没有注意,后来发现有副作用。
生成一个DetachedCriteria,调用完getCountByDetachedCriteria以后再调用findByDetachedCriteriaByPage返回的结果居然是一个Integer……
原来getCountByDetachedCriteria方法里面对detachedCriteria.getExecutableCriteria(session)产生的criteria设定了Projection,这也影响到了DetachedCriteria本身,以后再用它作查询都回返回Projection的结果。
现在的解决方法是手动擦屁股,重新set Null。(我原先以为final关键字会保证detachedCriteria不被修改,后来发现只是引用不能修改,实例本身可以随便修改)请问大家,有什么更好的解决方案么,我决得复杂一点的话这个detachedCriteria如何能擦除回来?
Reply from BJUG Groups by
whimet:
这个问题在javaeye上已经讨论过:
http://www.hibernate.org.cn/viewtopic.php?t=14657你这种情况还简单,若DetachedCriteria中包含排序设置就更不好办。
其实关键问题是DetachedCriteria.getExecutableCriteria返回的Criteria实例中已经包含了投影和排序信息,如果你想先查总数,
就得先去掉这些信息;查完总数,再查实际数据时,又得加上这些信息。而Criteria可没提供对它改来改去的接口。
不过,仔细考察一下DetachedCriteria可以发现,它类似一种暂存了查询条件的值对象,通过与一个session对象结合生成
一个“可执行的”Criteria,相当于先执行session.createCriteria,然后把自己保存的条件设置进去。
既然如此,我干脆自己提供一个类似的类,暂存查询条件,与session结合生成executableCriteria;但我先提供给用户一个只包含
查询条件的Criteria实例,让用户先拿着它去查总数;然后再提供加入投影和排序信息的方法,让用户拿着它去查数据,不就解决问题了。
-------------- 示例代码:
MyDetachedCriteria dc =
Criteria c = dc.getExecutableCriteria( session ); //这里的c只包含查询条件,不包括投影和排序
c.setProjection( Projections.rowCount() );
Integer total = (Integer) c.uniqueResult(); //得到总数
dc.fillProjectionSetting( c ); //把dc中保存的投影信息设置进去
dc.fillOrdersSetting( c ); //把dc中保存的排序信息设置进去
List data = c.list(); //取回数据
-------------- MyDetachedCriteria的代码:
/**
* 单独的值对象,用于暂存与Criteria相关的查询条件,并可与Session结合生成一个可执行的Criteria<br>
* <br>
* 该类继承自DetachedCriteria只是为了保持接口兼容性,其实与DetachedCriteria没关系 <br>
* (之所以叫“Detached”,是指与Session脱离)
*/
public class MyDetachedCriteria extends DetachedCriteria {
private Class entityClass;
private ArrayList criterions = new ArrayList();
private ArrayList orders = new ArrayList();
private Projection projection;
/**
* @param entityClass
*/
public MyDetachedCriteria( Class entityClass ) {
super( entityClass.getName() );
this.entityClass = entityClass;
}
/**
* @see org.hibernate.criterion.DetachedCriteria#add(org.hibernate.criterion.Criterion)
*/
public DetachedCriteria add( Criterion criterion ) {
criterions.add( criterion );
return this;
}
/**
* @see org.hibernate.criterion.DetachedCriteria#addOrder(org.hibernate.criterion.Order)
*/
public DetachedCriteria addOrder( Order order ) {
orders.add( order );
return this;
}
/**
* @see org.hibernate.criterion.DetachedCriteria#setProjection(org.hibernate.criterion.Projection)
*/
public DetachedCriteria setProjection( Projection projection ) {
this.projection = projection;
return this;
}
// ---------------------------------------------------------------------------
/**
* 根据Session实例创建一个Criteria实例,并填充入此对象自身保存的条件后返回<br>
* 注意:返回的Criteria实例不含排序和投影信息,用户需要自己调用fillOrdersSetting、
* fillProjectionSetting填充入排序和投影信息
*
* @see org.hibernate.criterion.DetachedCriteria#getExecutableCriteria(org.hibernate.Session)
*/
public Criteria getExecutableCriteria( Session session ) {
Criteria result = session.createCriteria( entityClass );
for ( Iterator i = criterions.iterator(); i.hasNext(); ) {
Criterion criterion = ( Criterion ) i.next();
result.add( criterion );
}
return result;
}
/**
* 填充入排序信息设置
*
* @param criteria
* @return
*/
public Criteria fillOrdersSetting( Criteria criteria ) {
for ( Iterator i = orders.iterator(); i.hasNext(); ) {
Order order = ( Order ) i.next();
criteria.addOrder( order );
}
return criteria;
}
/**
* 填充入投影信息设置
*
* @param criteria
* @return
*/
public Criteria fillProjectionSetting( Criteria criteria ) {
criteria.setProjection( projection );
return criteria;
}
}
Update 2006-6-6 20:52:
恩,谢谢诸位。想了想还是DetachedCriteria设计的目的和我想要的不一样。DetachedCriteria目前只是为了脱离session就可以构造,而并不是为了反复使用。
因为:1、它里面只包装了一个CriteriaImpl,所以实际上两者生命周期比较一致。而且每次getExecutableCriteria都直接返回这个CriteriaImpl,而不是重新创建,这就造成了容易被意外修改。 2、它没有提供与add对应的remove方法,这就造成它只能累积而不能擦拭(对于Order),用反射就太脏了。
whimet写的这个MyDetachedCriteria倒是可以解决问题,更符合我们想要复用DetachedCriteria的需求,不过我觉得调用起来接口上不太统一。Order和Projection一般不用复用,我想就可以不用实现DetachedCriteria接口,干脆修改GenericDAO的方法好了,写个接受List<Criteria>或者Criteria...的方法对应就可以了。反正觉得DetachedCriteria目前的实现是不如意,hack它吧……我就想提供remove这些Order和Projection的方法。
这里用反射解决了他遇到的Order的问题,大家可以参考,看来DetachedCriteria目前实现的还不够令人满意:
关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
分享到:
相关推荐
"Hibernate - DetachedCriteria 的完整用法" Hibernate 的 Criteria 和 DetachedCriteria 是两个不同的概念,虽然它们都是用于查询数据的,但它们在创建和使用上有所不同。 首先,Criteria 是在线的,需要通过 ...
《深入解析HibernateDao.java》 在Java开发领域,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。本文将深入探讨`HibernateDao.java`这一关键组件,揭示其背后的原理与实践应用。 `...
**Hibernate 框架及其DetachedCriteria操作详解** Hibernate 是一个强大的Java持久化框架,它极大地简化了数据库操作,使得开发者能够用面向对象的方式处理数据库事务。本篇将深入探讨Hibernate中的...
HibernateDao 是一种基于 Hibernate ORM(对象关系映射)框架的通用数据访问对象,它简化了对数据库的操作,提供了更高级别的抽象,使开发者能够更加专注于业务逻辑而不是底层的数据操作。在Java开发中,Hibernate...
hibernateDao工具类
Hibernate DAO(Data Access Object)生成工具是用于自动化创建数据访问层对象的实用程序,它可以显著提高开发效率,尤其是在处理大量数据库交互的项目中。DAO模式是一种设计模式,它提供了对数据库操作的抽象,使得...
本文将深入探讨如何使用代理来实现Hibernate Dao层的自动事务管理,以提高代码的可维护性和事务处理的效率。 首先,理解Dao(Data Access Object)层的作用至关重要。Dao层是应用与数据库之间的一层抽象,它封装了...
《深入理解HibernateDAO的写法》 在Java企业级开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。而HibernateDAO则是基于Hibernate进行数据访问的对象,是业务逻辑层和持久层之间...
Hibernate DAO生成器是专门为Hibernate框架设计的工具,能够自动生成与数据库表对应的DAO类。这些DAO类包含了根据Hibernate的配置文件自动创建的CRUD(Create、Read、Update、Delete)方法,使得开发者可以直接调用...
在Java开发中,DAO(Data Access Object)层是用于与数据库进行交互的接口或抽象类,主要用于隔离业务逻辑...通过以上步骤,我们可以构建一个高效且易于维护的Hibernate DAO层,为Java应用程序提供稳定的数据访问支持。
开发HIBERNATE,只要继承此类.一切变得简单多了. 继承的DAO类可一行代码实行增,删,改. 另外也支持查询.分页查询. 在事务方面还不完善. 代码是我自己写的.资源分要使用5点. 但大家可以在下载后点评一下.这样5点的积分...
本篇文章将深入探讨为什么DetachedCriteria无法直接支持表连接查询,并提供一些替代方案。 首先,DetachedCriteria主要用于离线查询,即不在当前Session内执行的查询。它的主要优势在于可以预编译查询条件,延迟到...
标题 "使用模式设计及java5新特性在HibernateDAO中的应用" 涉及到的是软件开发中的两个关键领域:设计模式和Java编程语言的新特性,特别是在数据访问对象(DAO)层如何结合使用它们。这篇文章可能详细阐述了如何利用...
- **含义**:此处的描述简略且不太清晰,但可以理解为这是关于一个通用Hibernate DAO的文本资料或文档。 - **作用**:提供了一个简单的文档说明,用于描述通用Hibernate DAO的设计思路和实现方法。 #### 三、标签:...
Haha.Hibernate SprintSideExt 通用HibernateDAO 文章资源 详见:http://blog.csdn.net/lijun7788/article/details/6658847
这是一个DAO代码生成工具,只需要配置好数据库连接信息,和按照你的需求配置要生成到的路径,运行BAT文件就会生成操作数据库的代码,可以完成增加,删除,修改,查询等操作,不需要写SQL语句,生成完全面向对象的代码....
在传统的Hibernate使用中,我们需要为每个实体类编写大量的CRUD(Create, Read, Update, Delete)方法,而使用原生通用DAO可以减少这部分重复工作,提高开发效率。 在设计原生通用DAO时,通常会包含以下核心功能: ...