写在前面:

  最近在项目中使用了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+分页的更多相关文章

  1. Hibernate 中Criteria Query查询详解【转】

    当查询数据时,人们往往需要设置查询条件.在SQL或HQL语句中,查询条件常常放在where子句中.此外,Hibernate还支持Criteria查询(Criteria Query),这种查询方式把查询 ...

  2. 分享知识-快乐自己:Hibernate 中Criteria Query查询详解

    1):Hibernate 中Criteria Query查询详解 当查询数据时,人们往往需要设置查询条件.在SQL或HQL语句中,查询条件常常放在where子句中. 此外,Hibernate还支持Cr ...

  3. mysql 查询去重 distinct

    mysql 查询去重 distinct   待完善内容..

  4. Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o

    Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o 1. Criteria,,Criterion ,, 1 <2. 主要的对象黑头配置磊 ...

  5. Hibernate之Criteria的完整用法

    Criteria的完整用法 QBE (Query By Example) Criteria cri = session.createCriteria(Student.class); cri.add(E ...

  6. Atitit.Hibernate于Criteria 使用汇总and 关系查询 and 按照子对象查询 o9o

    Atitit.Hibernate于Criteria 使用总结and 关联查询 and 依照子对象查询 o9o 1. Criteria,,Criterion ,, 1 <2. 基本的对象黑头配置磊 ...

  7. 转:Hibernate中Criteria和DetachedCriteria的完整用法

    原文地址:http://blog.sina.com.cn/s/blog_667528fd0100rkrf.html 设计上可以灵活的根据 Criteria 的特点来方便地进行查询条件的组装.现在对 H ...

  8. Hibernate中Criteria的完整用法2

    Criteria的完整用法 QBE (Query By Example) Criteria cri = session.createCriteria(Student.class); cri.add(E ...

  9. Hibernate中Criteria的完整用法

    1,CriteriaHibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供了 Criteria和DetachedCriteria .2,De ...

随机推荐

  1. python学习总结 --函数基础

    函数基础 ### 函数简介 - 定义:具有特定功能的一段代码 - 优点: - 可以减少代码的重复书写 - 可以将功能的实现着和使用者分开,可以提高开发效率 - 分类: - 库函数:print.inpu ...

  2. 课时40:类与对象:一些相关的BIF

    目录: 一.一些相关的BIF 二..课时40课后习题及答案 ********************** 一.一些相关的BIF ********************** 1.issubclass( ...

  3. Python读取不同文件夹下的图片并且分类放到新创建的训练文件夹和标签文件夹

    在深度学习的训练时,经常会碰到训练的样本数据集和标签数据集是在一个文件夹中,这个时候我们就不得不进行一些数据的预处理和文件的分类,例如将训练(training data)数据集和标签数据集(label ...

  4. Android之SeekBar总结(一)

    2015-04-24 SeekBar: 一种特殊的进度条,包含一个滑块用于调节进度值. API 中目录结构如下: 包含几种特殊的属性: 1: max:设置进度条的最大值 .对应方法:setMax(in ...

  5. intellij idea 2017 工具使用问题

    1.打开idea 打开maven项目报错:Unable to import maven project 2.在idea中Help->Show Log in Explorer->idea.l ...

  6. LINQ to Entities 不识别方法“System int string 转换的问题

    这个问题困扰了挺久,网上找了挺多方法 都太好使. 分几种情况. 1.如果查询结果 转换,那比较容易. var q = from c in db.Customers where c.Country == ...

  7. 【bzoj2959】长跑 LCT+并查集

    题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前.为了 ...

  8. 【bzoj1899】[Zjoi2004]Lunch 午餐 dp

    题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的口味(以及胃口)不同,所以他们要吃的菜各 ...

  9. mplab xIde 编译成功,但不能生成Hex文件

    设置不对 如果还不行,在设置下面

  10. [xsy1129] flow [树链剖分和线段树一起优化网络流][我也不知道这是什么鬼标签]

    题面 内部OJ 思路 考虑一个决策方案${x}$,$x_i$表示第$i$个点选不选,$f^k_i$表示点$i$的第$k$个父亲 那么可以得到总花费的表达式$ans=\sum V_i x_i - \su ...