`
micheal19840929
  • 浏览: 163211 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

DetachedCriteria分页记录重复解决方案

    博客分类:
  • J2EE
阅读更多

尝试了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

0
1
分享到:
评论

相关推荐

    Hibernate 使用DetachedCriteria操作

    - 在服务层进行分页查询时,可以先创建DetachedCriteria,然后在视图层根据请求参数调整限制条件,避免重复计算。 **4. DetachedCriteria 的基本用法** 创建DetachedCriteria通常从`DetachedCriteria.forClass()`...

    DetachedCriteria笔记

    DetachedCriteria

    DetachedCriteria查询

    DetachedCriteria 查询 DetachedCriteria 是 Hibernate 中的一种离线查询对象,它可以在不依赖 Session 的情况下生成动态 SQL 语句并进行查询。下面是 DetachedCriteria 查询的详细知识点: 创建 DetachedCriteria...

    DetachedCriteria使用介绍

    DetachedCriteria使用介绍

    Hibernate - DetachedCriteria 的完整用法

    "Hibernate - DetachedCriteria 的完整用法" Hibernate 的 Criteria 和 DetachedCriteria 是两个不同的概念,虽然它们都是用于查询数据的,但它们在创建和使用上有所不同。 首先,Criteria 是在线的,需要通过 ...

    浅谈DetachedCriteria和Criteria的使用方法(必看)

    在Web编程中,DetachedCriteria和Criteria可以解决动态条件查询的问题,提高程序的灵活性和可维护性。 DetachedCriteria的使用方法: DetachedCriteria是离线的查询工具,可以在Web层构造查询条件,然后将其传递给...

    Hibernate(24): 为什么用DetachedCriteria不能表连接地取数据?

    本篇文章将深入探讨为什么DetachedCriteria无法直接支持表连接查询,并提供一些替代方案。 首先,DetachedCriteria主要用于离线查询,即不在当前Session内执行的查询。它的主要优势在于可以预编译查询条件,延迟到...

    springMVC+hibernate的条件查询加分页的demo

    此外,为了方便前端展示,Service层通常会返回一个包含查询结果和分页信息的对象,如Page对象,这个对象不仅包含查询结果列表,还包含总记录数、总页数等信息。Controller接收到这个对象后,将其转换为JSON或其他...

    Hibernate+sqlserver2000分页

    在IT行业中,数据库分页是一项基础且重要的技术,特别是在大数据量的展示场景下,它能够有效地提高用户体验,避免一次性加载过多数据导致的性能问题。本篇文章将深入探讨使用Hibernate ORM框架与SQL Server 2000...

    DetachedCriteria Criteria 使用方法

    DetachedCriteria Criteria 使用方法 非常详细外加练习

    struts2+spring+hibernate分页查询

    Criteria API可以通过DetachedCriteria对象创建查询条件,然后调用setFirstResult和setMaxResults方法实现分页。HQL则通过LIMIT子句实现分页,但不适用于所有的数据库系统,因为它不是SQL标准的一部分。 **整合使用...

    Hibernate 在查询操作中要使用分页+命名参数+排序技术

    为解决这个问题,Hibernate提供了一种分页查询的方法。通过设置`firstResult`(起始索引)和`maxResults`(最大返回结果数)参数,我们可以指定每次查询的数据范围。例如,如果我们想要获取第5页,每页显示10条记录...

    sh分页,增删改查

    Criteria查询提供了动态构建查询的方式,可以通过DetachedCriteria实现分页;HQL是面向对象的查询语言,可以方便地进行分页;对于更复杂的SQL操作,可以直接使用SQL查询,并配合 ScrollableResults 接口实现分页。在...

    Hibernate 查询经典练习题

    在MySQL中,使用`LIMIT`关键字进行分页,这里展示第2页(即从第1条记录开始,每页3条记录)。 #### HQL分页 ```java public void show(int page, int num) { String hql = "SELECT s.ename, s.empno FROM Emp s ...

    Hibernate中查询的法方

    为了解决这个问题,可以在`DetachedCriteria`中设置相应的查询条件,以实现带条件的分页查询。 通过理解和熟练运用这些基本查询方法,你可以有效地利用Hibernate进行数据操作,从而提高开发效率。在实际项目中,还...

    hibernate_criterion.rar

    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class); detachedCriteria.add(Expression.eq("username", "admin")); List&lt;User&gt; users = session.createCriteria(User.class)....

    留言板代码定义.pdf

    代码中实现了分页功能,`Paginate`类用于处理分页逻辑。`paginate`对象根据查询结果的总数初始化,并通过用户操作(如“上一页”,“下一页”,“首页”,“末页”)更新当前页码。 7. **ServletActionContext**:...

    Hibernate的Criteria用法

    DetachedCriteria detchedCriteria = DetachedCriteria.forClass(Person.class); detchedCriteria.add(Restrictions.ge("age", new Integer(25))); ``` 当你需要执行查询时,再将DetachedCriteria转换为Criteria...

    hibernate3.2-中文帮助文档

    1. **Hibernate 概述**:文档首先介绍了Hibernate的核心概念,包括持久化、对象关系映射以及Hibernate如何作为解决方案来简化数据访问层的开发。这部分会解释ORM的基本原理,以及Hibernate如何将Java对象与数据库表...

    Hibernate的Criteria用法总结

    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class); detachedCriteria.add(Restrictions.eq("status", "active")); userList = getHibernateTemplate().findByCriteria...

Global site tag (gtag.js) - Google Analytics