尝试了criterion.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)方法发现Hibernate其实只是针对结果集再过滤,得到的记录总数仍然是含有重复的
经过一番尝试,决定使用子查询来解决这个问题,以下代码已经测试通过:
Payment payment=new Payment();
User user=new User();
payment.setType(null);
user.setUid(uid);
//获得查询条件的实体
DetachedCriteria criteria=DetachedCriteria.forClass(Payment.class,"inner");
//对ID进行投影
criteria.setProjection(Projections.distinct(Property.forName("id")));
//创建 Example,注意Subscribe实例包含有User实例及Product实例,这里要分开创建example
Example example=Example.create(payment).ignoreCase().excludeNone().excludeZeroes();
criteria=criteria.add(example.excludeNone().excludeZeroes());
if(paymentStates!=null&&paymentStates.length>0)
{
criteria.add(Property.forName("state").in(paymentStates));
}
if(start!=null)
{
if(end!=null)
{
criteria.add(Restrictions.between("createDatetime",start,end));
}
else
{
criteria.add(Restrictions.between("createDatetime",start,new Date()));
}
}
else
{
if(end!=null)
criteria.add(Restrictions.between("createDatetime",new Date(0),end));
}
//多对多查询
criteria=criteria.createAlias("subscribes","ss");
criteria.createCriteria("ss.user",Criteria.LEFT_JOIN)
.add(Example.create(user).ignoreCase().excludeNone().excludeZeroes());
if(productIds!=null&&productIds.length>0)
{
criteria.createCriteria("ss.product",Criteria.LEFT_JOIN)
.add(Restrictions.in("id",productIds));
}
//使用子查询,从ID再查询记录
DetachedCriteria fullCriteria = DetachedCriteria.forClass(Payment.class,"outer").add(Subqueries.propertyIn("id", criteria));
fullCriteria.addOrder(Order.desc("updateDatetime"));
return paymentDao.findPageByCriteria(fullCriteria, pageIndex,numPerPage);
以及对应的分页方法:
public PageBean findPageByCriteria(final DetachedCriteria detachedCriteria,
final int pageIndex, final int numPerPage) {
final int start = (pageIndex - 1) * numPerPage;
return (PageBean) hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Criteria criteria = detachedCriteria
.getExecutableCriteria(session);
// 先去掉Order部分
List orderEntrys = null;
Field field = null;
CriteriaImpl impl = (CriteriaImpl) criteria;
try {
field = CriteriaImpl.class.getDeclaredField("orderEntries");
field.setAccessible(true);// 这是要害:)
orderEntrys = (List) field.get(impl);
field.set(criteria, new ArrayList());
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
// 获取总记录数
int totalCount = ((Integer) criteria.setProjection(
Projections.rowCount()).uniqueResult()).intValue();
criteria.setProjection(null);
criteria
.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
// 再恢复Order部分
List innerOrderEntries = null;
try {
innerOrderEntries = (List) field.get(criteria);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
for (int i = 0; i < orderEntrys.size(); i++) {
innerOrderEntries.add(orderEntrys.get(i));
}
List items = criteria.setFirstResult(start).setMaxResults(
numPerPage).list();
PageBean pb = new PageBean();
pb.setRecordList(items);
pb.setNumPerPage(numPerPage);
pb.setPageIndex(pageIndex);
;
pb.setTotalRecord(totalCount);
return pb;
}
});
}
参考文档:http://blog.fryhard.com/archive/2009/05/26/selecting-distinct-records-using-castle-activerecord.aspx
分享到:
相关推荐
- 在服务层进行分页查询时,可以先创建DetachedCriteria,然后在视图层根据请求参数调整限制条件,避免重复计算。 **4. DetachedCriteria 的基本用法** 创建DetachedCriteria通常从`DetachedCriteria.forClass()`...
DetachedCriteria
DetachedCriteria 查询 DetachedCriteria 是 Hibernate 中的一种离线查询对象,它可以在不依赖 Session 的情况下生成动态 SQL 语句并进行查询。下面是 DetachedCriteria 查询的详细知识点: 创建 DetachedCriteria...
"Hibernate - DetachedCriteria 的完整用法" Hibernate 的 Criteria 和 DetachedCriteria 是两个不同的概念,虽然它们都是用于查询数据的,但它们在创建和使用上有所不同。 首先,Criteria 是在线的,需要通过 ...
### DetachedCriteria 使用详解 #### 一、基本使用 **1. 说明** `DetachedCriteria` 是 Hibernate 提供的一种灵活且强大的查询机制,它允许你在脱离 Session 的情况下构建复杂的查询标准,这意味着你可以提前构建...
在Web编程中,DetachedCriteria和Criteria可以解决动态条件查询的问题,提高程序的灵活性和可维护性。 DetachedCriteria的使用方法: DetachedCriteria是离线的查询工具,可以在Web层构造查询条件,然后将其传递给...
本篇文章将深入探讨为什么DetachedCriteria无法直接支持表连接查询,并提供一些替代方案。 首先,DetachedCriteria主要用于离线查询,即不在当前Session内执行的查询。它的主要优势在于可以预编译查询条件,延迟到...
此外,为了方便前端展示,Service层通常会返回一个包含查询结果和分页信息的对象,如Page对象,这个对象不仅包含查询结果列表,还包含总记录数、总页数等信息。Controller接收到这个对象后,将其转换为JSON或其他...
在IT行业中,数据库分页是一项基础且重要的技术,特别是在大数据量的展示场景下,它能够有效地提高用户体验,避免一次性加载过多数据导致的性能问题。本篇文章将深入探讨使用Hibernate ORM框架与SQL Server 2000...
为了解决这些问题,`DetachedCriteria` 应运而生。它允许在Web层构造查询条件,并将其作为参数传递给业务层对象,从而实现查询语句构造的完全解耦。这样,业务层仅需关注数据的持久化和查询封装,而不必关心具体的...
Criteria API可以通过DetachedCriteria对象创建查询条件,然后调用setFirstResult和setMaxResults方法实现分页。HQL则通过LIMIT子句实现分页,但不适用于所有的数据库系统,因为它不是SQL标准的一部分。 **整合使用...
为解决这个问题,Hibernate提供了一种分页查询的方法。通过设置`firstResult`(起始索引)和`maxResults`(最大返回结果数)参数,我们可以指定每次查询的数据范围。例如,如果我们想要获取第5页,每页显示10条记录...
Criteria查询提供了动态构建查询的方式,可以通过DetachedCriteria实现分页;HQL是面向对象的查询语言,可以方便地进行分页;对于更复杂的SQL操作,可以直接使用SQL查询,并配合 ScrollableResults 接口实现分页。在...
在MySQL中,使用`LIMIT`关键字进行分页,这里展示第2页(即从第1条记录开始,每页3条记录)。 #### HQL分页 ```java public void show(int page, int num) { String hql = "SELECT s.ename, s.empno FROM Emp s ...
为了解决这个问题,可以在`DetachedCriteria`中设置相应的查询条件,以实现带条件的分页查询。 通过理解和熟练运用这些基本查询方法,你可以有效地利用Hibernate进行数据操作,从而提高开发效率。在实际项目中,还...
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class); detachedCriteria.add(Expression.eq("username", "admin")); List<User> users = session.createCriteria(User.class)....
代码中实现了分页功能,`Paginate`类用于处理分页逻辑。`paginate`对象根据查询结果的总数初始化,并通过用户操作(如“上一页”,“下一页”,“首页”,“末页”)更新当前页码。 7. **ServletActionContext**:...
DetachedCriteria detchedCriteria = DetachedCriteria.forClass(Person.class); detchedCriteria.add(Restrictions.ge("age", new Integer(25))); ``` 当你需要执行查询时,再将DetachedCriteria转换为Criteria...
1. **Hibernate 概述**:文档首先介绍了Hibernate的核心概念,包括持久化、对象关系映射以及Hibernate如何作为解决方案来简化数据访问层的开发。这部分会解释ORM的基本原理,以及Hibernate如何将Java对象与数据库表...
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class); detachedCriteria.add(Restrictions.eq("status", "active")); userList = getHibernateTemplate().findByCriteria...