设为首页收藏本站

IT技术擎 - 最棒的IT web技术交流社区

 找回密码
 注册为IT技术擎人

QQ登录

只需一步,快速开始

搜索
热搜: php h5 jquery
查看: 53|回复: 0

[框架开发] Hibernate使用Criteria去重distinct+分页

[复制链接]

1万

主题

1万

帖子

4万

积分

版主

Rank: 7Rank: 7Rank: 7

积分
40184
发表于 2018-8-3 22:05:24 | 显示全部楼层 |阅读模式

写在前面:  最近在项目中使用了Criteria的分页查询,当查询的数据没有重复的记录还好,但是当数据有关联并出现重复记录的时候,就要去重,那么就会出现查询的记录数与实际的不一致的问题。这里也记录一下解决的办法。
  这里只是拿学生Student表与班级来举例,没有经过测试
  1.查询全部的数据,不进行分页处理,使用distinct去重完全是可以的,代码大致如下:
  1. /** * 查询所有的学生 不分页去重 * @return * @throwsException */ publicList <Student > listAllStudent() throwsException { Session session = this.getCurrentSession(); Criteria criteria = session.createCriteria(Student.class);//去重 不分页 criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); List <Student > list =criteria.list();returnlist; }
复制代码
  2.查询全部的数据,但是要分页查询。先来看下出问题的代码,大致如下:
  1. /** * 查询所有的学生 分页去重 * 问题代码 此种方式当有复杂的关联关系时 查出来的数据记录会与实际的不一致 * @return * @throwsException */ publicList <Student > listAllStudent2() throwsException { 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();returnlist; }
复制代码
  一般情况下,我们都会使用上面的代码,但是经过数据的测试就会发现,分页后查询出来的代码虽然去重了,但是数据的记录条数会出问题,与实际的并不一致。之所以会出现这样的问题,是因为,上面的代码的执行顺序是查询出所有符合条件的记录,然后是先分页,分页分好了,再去重,那如果查询出来的第一页数据有3条,里面有两个记录是重复的,那么经过去重后,第一页显示出来的数据就只有2条;而我们正常分页去重的顺序应该是,先查询出所有符合条件的记录,然后去重,最后才是在分页。
  下面就提供一种解决方案。大致的代码如下:
  1. /** * 查询所有的学生 分页去重 正确的打开方式 * @return * @throwsException */ publicList <Student > listAllStudent3() throwsException { 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
  2. ).list();//2.重新构建criteria查询 Criteria criteria2 = session.createCriteria(Student.class); List <Student > resultList = newArrayList <Student >();//3.查询所有studentId在studentIdList里的Student if(studentIdList.size() >0){ criteria2.add(Restrictions.in("studentId",studentIdList));//这里才使用去重不需要再次分页了 criteria2.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); resultList =criteria2.list(); }returnresultList; }
复制代码
  上面代码基本就完成了使用Criteria查询,并且可以分页,可以去重。大致步骤可以分为三个部分:
    举例:表a,表b,两个表有关联关系,现在要查询出所有符合条件的a记录,并且使用分页查询
    1.分页查询出所有的a的唯一标识属性集合list,注意这里要进行分页    2.再次重新构建criteria查询
    3.查询出所有a的唯一属性包含在list集合中的a记录,并去重  当然了,这只是个大致的步骤,具体的代码还要根据自己的项目来看,对了,还要稍微注意下,当Criteria查询使用别名的时候,记得选择合适自己项目的连接方式,比如,当表a中有外键与表b关联,当a的外键是null的时候,要想查询此条记录出来,要使用表a左外连接表b的方式来进行查询
该用户未在地球留下任何的痕迹

本版积分规则

QQ|小黑屋|帮助|IT技术擎 ( 沪ICP备15054863号  

GMT+8, 2018-10-18 10:45

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表