Hibernate使用Criteria去重distinct+分页
写在前面:
最近在项目中使用了Criteria的分页查询,当查询的数据没有重复的记录还好,但是当数据有关联并出现重复记录的时候,就要去重,那么就会出现查询的记录数与实际的不一致的问题。这里也记录一下解决的办法。
这里只是拿学生Student表与班级来举例,没有经过测试
1.查询全部的数据,不进行分页处理,使用distinct去重完全是可以的,代码大致如下:
/**
* 查询所有的学生 不分页去重
* @return
* @throws Exception
*/
public List<Student> listAllStudent() throws Exception {
Session session = this.getCurrentSession();
Criteria criteria = session.createCriteria(Student.class);
//去重 不分页
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List<Student> list = criteria.list();
return list;
}
2.查询全部的数据,但是要分页查询。先来看下出问题的代码,大致如下:
/**
* 查询所有的学生 分页去重
* 问题代码 此种方式当有复杂的关联关系时 查出来的数据记录会与实际的不一致
* @return
* @throws Exception
*/
public List<Student> listAllStudent2() throws Exception {
Session session = this.getCurrentSession();
Criteria criteria = session.createCriteria(Student.class);
//去重 会出现数据记录数不一致问题
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
//分页
List<Student> list = criteria.setFirstResult(0).setMaxResults(5).list();
return list;
}
一般情况下,我们都会使用上面的代码,但是经过数据的测试就会发现,分页后查询出来的代码虽然去重了,但是数据的记录条数会出问题,与实际的并不一致。之所以会出现这样的问题,是因为,上面的代码的执行顺序是查询出所有符合条件的记录,然后是先分页,分页分好了,再去重,那如果查询出来的第一页数据有3条,里面有两个记录是重复的,那么经过去重后,第一页显示出来的数据就只有2条;而我们正常分页去重的顺序应该是,先查询出所有符合条件的记录,然后去重,最后才是在分页。
下面就提供一种解决方案。大致的代码如下:
/**
* 查询所有的学生 分页去重 正确的打开方式
* @return
* @throws Exception
*/
public List<Student> listAllStudent3() throws Exception {
Session session = this.getCurrentSession();
Criteria criteria = session.createCriteria(Student.class);
//1.分页查询出所有的Student的唯一标识studentId
criteria.setProjection(Projections.distinct(Property.forName("studentId")));
List<String> studentIdList = criteria.setFirstResult(0).setMaxResults(5).list();
//2.重新构建criteria查询
Criteria criteria2 = session.createCriteria(Student.class);
List<Student> resultList = new ArrayList<Student>();
//3.查询所有studentId在studentIdList里的Student
if(studentIdList.size()>0){
criteria2.add(Restrictions.in("studentId",studentIdList));
//这里才使用去重 不需要再次分页了
criteria2.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
resultList = criteria2.list();
}
return resultList;
}
上面代码基本就完成了使用Criteria查询,并且可以分页,可以去重。大致步骤可以分为三个部分:
举例:表a,表b,两个表有关联关系,现在要查询出所有符合条件的a记录,并且使用分页查询
1.分页查询出所有的a的唯一标识属性集合list,注意这里要进行分页
2.再次重新构建criteria查询
3.查询出所有a的唯一属性包含在list集合中的a记录,并去重
当然了,这只是个大致的步骤,具体的代码还要根据自己的项目来看,对了,还要稍微注意下,当Criteria查询使用别名的时候,记得选择合适自己项目的连接方式,比如,当表a中有外键与表b关联,当a的外键是null的时候,要想查询此条记录出来,要使用表a左外连接表b的方式来进行查询
Hibernate使用Criteria去重distinct+分页的更多相关文章
- Hibernate 中Criteria Query查询详解【转】
当查询数据时,人们往往需要设置查询条件.在SQL或HQL语句中,查询条件常常放在where子句中.此外,Hibernate还支持Criteria查询(Criteria Query),这种查询方式把查询 ...
- 分享知识-快乐自己:Hibernate 中Criteria Query查询详解
1):Hibernate 中Criteria Query查询详解 当查询数据时,人们往往需要设置查询条件.在SQL或HQL语句中,查询条件常常放在where子句中. 此外,Hibernate还支持Cr ...
- mysql 查询去重 distinct
mysql 查询去重 distinct 待完善内容..
- Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o
Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o 1. Criteria,,Criterion ,, 1 <2. 主要的对象黑头配置磊 ...
- Hibernate之Criteria的完整用法
Criteria的完整用法 QBE (Query By Example) Criteria cri = session.createCriteria(Student.class); cri.add(E ...
- Atitit.Hibernate于Criteria 使用汇总and 关系查询 and 按照子对象查询 o9o
Atitit.Hibernate于Criteria 使用总结and 关联查询 and 依照子对象查询 o9o 1. Criteria,,Criterion ,, 1 <2. 基本的对象黑头配置磊 ...
- 转:Hibernate中Criteria和DetachedCriteria的完整用法
原文地址:http://blog.sina.com.cn/s/blog_667528fd0100rkrf.html 设计上可以灵活的根据 Criteria 的特点来方便地进行查询条件的组装.现在对 H ...
- Hibernate中Criteria的完整用法2
Criteria的完整用法 QBE (Query By Example) Criteria cri = session.createCriteria(Student.class); cri.add(E ...
- Hibernate中Criteria的完整用法
1,CriteriaHibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供了 Criteria和DetachedCriteria .2,De ...
随机推荐
- winform-实现类似QQ停靠桌面上边缘隐藏的效果
//实现类似QQ停靠桌面上边缘隐藏的效果! private void timer1_Tick(object sender, EventArgs e) { System.Drawing.Point pp ...
- java IO小结
package 字符与字节转换; import java.io.*; public class char_byte { public static void main(String[] args) { ...
- 不作伪分享者决定完整分享我自学Python3的全部过程细节
不作伪分享者决定完整分享我自学Python3的全部过程细节 我不要作伪分享者 十六年前我第一次见到了电脑,并深深地爱上了它: 十二年前我第一次连上了网络,并紧紧地被它爱上. 十年前的网络是田园美景 ...
- 课时5:闲聊之Python的数据类型
目录: 一.引言 二.数据类型 >整型 >浮点型 >布尔类型 三.类型转换 四.获得关于类型的信息 五.课时05课后习题及答案 *********** 一.引言 ********** ...
- htmlagilitypack解析html
这是个很好的的东西,以前做Html解析都是在用htmlparser,用的虽然顺手,但解析速度较慢,碰巧今天找到了这个,就拿过来试,一切出乎意料,非常爽,推荐给各位使用. 下面是一些简单的使用技巧,希望 ...
- C#后端调用前端的方法
在我实际开发过程中,刚好遇到c#后端要调用前端js中的方法,所以研究了一下,特分享如下: 前端代码: <%@ Page Language="C#" AutoEventWire ...
- dirname(__FILE__)
dirname() 函数返回路径中的目录部分. __FILE__ :被称为PHP魔术常量,返回当前执行PHP脚本的完整路径和文件名,包含一个绝对路径 dirname(__FILE__) 函数返回的是脚 ...
- 网站前后台分离 图片 flash 视频 等文件的共享问题
在网上找了,没有说到点子上的,不详细 问了有经验的同事,要建立 文件服务器,就是一个IIS 下的新网站,网站是共享图片 文件使用的专用网站 后台上传的图片保存在 文件服务器即 文件共享专用的网站目录地 ...
- WebIDE
1 1 1 WebIDE 是什么? WebIDE 是 一款在线集成开发环境( Integrated Development Environment ). 开发者只需要一个浏览器就可以编写代码,并在We ...
- [bzoj4945][Noi2017]游戏
题目大意:有$n$个位置,有三种数,每个位置只可以填一种数,$d(d\leqslant8)$个位置有三种选择,其他位置只有两种选择.有一些限制,表示第$i$个位置选了某种数,那么第$j$个位置就只能选 ...