目录

学习背景与使用步骤

使用specification进行动态分页查询案例演示,包含按时间的范围查询


学习背景与使用步骤

最近在项目中遇到一个需求:对单个或者是多个条件进行分页查询(写在一个接口中),比如前端可能会传  name的模糊名,一个具体的字段,开始时间和结束时间,这四个参数可以组合传到你的后端接口来,所以我们需要对这种业务进行动态查询,而且查询出来的数据可能会非常的多,所以还需要对这些数据进行分页展示。所以我把这种业务情况称为动态条件分页查询,这里我使用的是jap中的specification的动态查询来实现这个功能。

使用specification进行动态分页查询的步骤如下:

  • 继承接口JpaSpecificationExecutor(里面的泛型是我们需要查询的实体,比如我们要对用户进行分页查询,那么这个user实体类需要和数据库中的一张表进行映射,这个泛型就是与数据库中表映射的java实体类
  • 传入Specification的实现(构建查询条件): 结合lambda表达式
    • Root:查询哪个表(表映射的java实体类,其中使用root对象获取属性的时候,参数传的是实体类中的属性名,不是表中的字段名) 相当于关键字 from

    • CriteriaQuery:查询哪些字段,排序是什么 相当于组合(order by . where )

    • CriteriaBuilder:条件之间是什么关系,如何生成一个查询条件,每一个查询条件都是什么类型(> between in...) = where

    • Predicate(Expression): 每一条查询条件的详细描述

    • root对象可以让我们从表中获取我们想要的列
                  /CriteriaBuilder where 设置各种条件  (> < in between......)
                  /query  组合(order by , where)

  • 使用jpa提供的api进行分页查询,把刚刚构建好的动态查询条件传入就行,注意这里返回的分页结果的泛型是继承JpaSpecificationExecutor这个接口中的泛型

使用specification进行动态分页查询案例演示,包含按时间的范围查询

写下面的代码遇到的几个思考问题,希望可以帮助更好的理解这个specification的使用:

  1. 分页查询的结果集是由哪个泛型决定的?继承JobWarnDtoJpa这个接口的泛型决定了分页查询的结果。
  2. root.get("name");的时候里面的字符串是数据库的字段名还是与数据库映射的实体类中的属性?实体类中的属性。
  3. 使用Specification构建动态查询条件的时候,Specification的泛型是什么?--->我们需要的分页结果中的泛型,比如我们需要对JobDto进行分页展示,那么Specification的泛型就是JobDto。(要明白:查询是从数据库中的表进行查询的,然后使用的第三方的api会帮我们把查询出来的数据映射封装到与表对应的实体类中,所以使用这种技术是需要表与实体类进行映射(这个是个人自己根据经验发表的哈,如果有问题希望大佬指正),当然为了更加方便的查询展示数据,实际上我们是可以使用视图来与dto进行对应,这样在查询数据这一方面就可以轻松的结合这种第三方工具来进行查询了)
  4. 使用criteriaBuilder构建动态查询条件的时候,括号中的第一个参数是与表对应的Java实体类属性(框架会帮我们映射到表中的字段中去),第二个参数是我们传过来的查询条件。比如需要对name进行模糊查询,那么第一个参数就是与表对应的实体类的name属性,第二个参数就是其他地方传过来的name(查询条件)

代码如下:

这个继承相当于mybatis中的dao或者是mapper层。

public interface DtoJpa extends JpaRepository<Dto, Long>, JpaSpecificationExecutor<Dto> {
}

通过接收前端的查询条件来动态的拼接查询条件:理解了criteriaBuilder.like(name, "%"+dto.getName()+"%")这个拼接条件的代码的背后的SQL,那就理解的差不多了。

/*** 通过Specification构建动态查询条件* @param dto 前端传过来的查询条件,因为可能参数比较多,所以我们创建了dto来承接这些查询条件,方便后期维护* @return specification 返回构建好的动态查询条件*/
public Specification<Dto> createSpecification(PageDto dto) {Specification<Dto> specification =new Specification<Dto>() {@Overridepublic Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {//构建查询条件   注意这里的  name startTime endTime 都是java实体类中的属性名Path<String> name = root.get("name");Path<Date> startTime = root.get("startTime");Path<Date> endTime = root.get("endTime");//用来存放查询条件ArrayList<Predicate> list = new ArrayList<>();//进行模糊查询的条件拼接if (!StringUtils.isEmpty(dto.getName())) {//使用这个进行模糊查询,需要自己拼接百分号到查询条件//这里实际上就相当于 ... like name = "%dto.getName()%"list.add(criteriaBuilder.like(name, "%"+dto.getName()+"%"));}//使用specification进行时间范围查询if (dto.getStartTime() !=null && dto.getEndTime()!=null) {//开始时间list.add(criteriaBuilder.greaterThanOrEqualTo(startTime,dto.getStartTime()));list.add(criteriaBuilder.lessThanOrEqualTo(endTime,dto.getEndTime()));}// 组合条件  因为涉及动态查询,这个拼接的查询条件个数在上面的判断中已经确定,这里需要我们传一个数组过来,通过集合转数组的方法进行转换,不过需要的是Prediccate类型的定长数组Predicate and = criteriaBuilder.and(list.toArray(new Predicate[list.size()]));return and;}};return specification;
}@autowire
private DtoJpa dtoJpa;/*** 通过Specification进行条件分页查询* @param currentPage       当前页面* @param pageSize          每页存放的数据条数* @param dto 动态分页查询的条件* @return result 返回分页查询结果*/
public Page<Dto> page(Integer currentPage, Integer pageSize, PageDto dto) {//这里的createSpecification方法就是上面我们构建动态条件的方法Specification<Dto> specification = this.createSpecification(dto);//默认是从第1页开始,但是数据展示是从第0页开始的,所以需要减1判断Pageable pageable = PageRequest.of((currentPage - 1) > 0 ? (currentPage - 1) : 0, pageSize);//第一个参数是封装好的查询条件   这个findAll是jpa原生提供的,只需要继承JpaSpecificationExecutor就行Page<Dto> result = dtoJpa.findAll(specification, pageable);return result;
}

specification不支持分组等相关聚合函数的操作,但是支持排序 。是可以进行组合操作的,比如还可以在上面的返回值and上再进行拼接:

//对id字段进行降序排序
                Order desc = criteriaQuery.desc(Id);

//使用呢query对象对条件和组合进行拼接
                return criteriaQuery.where(and).orderBy(desc).getRestriction();

使用jap的specification动态查询的演示案例与一些注意事项相关推荐

  1. spring data jpa封装specification实现简单风格的动态查询

    github:https://github.com/peterowang/spring-data-jpa-demo 单一实体的动态查询: @Servicepublic class AdvancedUs ...

  2. jpa 动态查询条件 数组_Spring data jpa 复杂动态查询方式总结

    一.Spring data jpa 简介 首先JPA是Java持久层API,由Sun公司开发, 希望整合ORM技术,实现天下归一.  诞生的缘由是为了整合第三方ORM框架,建立一种标准的方式,目前也是 ...

  3. Spring-Data-JPA 动态查询黑科技

    在开发中,用到动态查询的地方,所有的查询条件包括分页参数,都会被封装成一个查询类XxxQuery 比如说上一篇中的Item 那么ItemQuery就像这样 @Data public class Ite ...

  4. Mybatis+MySQL动态分页查询数据经典案例

    最近在用Mybatis做项目的时候遇到了不少问题,今天我就在这和大家分享一下,稀稀拉拉的研究了两天,终于搞好了! 开发人员:1111 开发软件:Myeclipse 用到的框架技术:Mybatis 数据 ...

  5. Mybatis+MySQL动态分页查询数据经典案例(含代码以及测试)

    最近在用Mybatis做项目的时候遇到了不少问题,今天我就在这和大家分享一下,稀稀拉拉的研究了两天,终于搞好了! 开发人员:1111 开发软件:Myeclipse 用到的框架技术:Mybatis 数据 ...

  6. querydsl动态 sql_Spring data jpa 复杂动态查询方式总结

    一.Spring data jpa 简介 首先JPA是Java持久层API,由Sun公司开发, 希望整合ORM技术,实现天下归一.  诞生的缘由是为了整合第三方ORM框架,建立一种标准的方式,目前也是 ...

  7. SpringDataJpa (二)-动态查询多表操作

    SpringDataJpa (二)-动态查询&多表操作 一.动态查询 1.Specifications动态查询 1.1 搭建测试环境 1.1.1 导入坐标 1.1.2 创建客户实体类 1.1. ...

  8. Spring之Specification复杂查询和Criteria查询

    Specification官网 [一目了然]Spring Data JPA使用Specification动态构建多表查询.复杂查询及排序示例 JPA 使用 Specification 复杂查询和 Cr ...

  9. SpringBoot JPA(JpaRepository)动态查询 分页展示

    大家知道Hibernate可以很轻松的根据提供条件进行动态筛选查询,那个JPA怎么实现呢,其中最为简单的就是使用Specification实现JPA的动态查询,本人也是初步接触JPA,第一次使用JPA ...

最新文章

  1. win 对比工具-Araxis Merge
  2. python生成器单线程_【Python】迭代器、生成器、yield单线程异步并发实现详解
  3. okhttp 工具类_HR常用的人才测评工具 ~ 团测系统
  4. 初次使用mybatis Generator
  5. C# 是否可以将 动态或匿名类型 转成 强类型 ?
  6. Android插件化开发基础之Java反射机制研究
  7. Android项目目录结构
  8. MySQL入门 (一) : 资料库概论与MySQL的安装
  9. 基于shiro实现session持久化和分布式共享
  10. Spring3 MVC请求参数获取的几种场景
  11. fiddler模拟服务器响应,fiddler模拟返回响应数据
  12. 我是怎么找电子书的?
  13. centos7 默认启动项_如何在centos7中搭建 ISCSI 服务
  14. MS SQL 表字段增加,删除,修改
  15. seo攻略书籍_推荐几本适合SEOer初学级书籍
  16. 如何破解锐捷支持多网卡
  17. python中ahp的代码_AHP | 层次分析法原理及Python实现
  18. 微型计算机怎么插入光盘,解决Win 7读光盘“请将磁盘插入DVD驱动器”故障
  19. python代码,用于获取mp3部分信息并存入MySQL中
  20. 任正非语录(华为家事)

热门文章

  1. 软件测试,浅析这项黑色艺术的难与易
  2. 软件测试讲师-金老师
  3. Nginx 安全配置
  4. 2018“百越杯”第四届福建省高校网络空间安全大赛部分题目writeup
  5. android分辨率hdpi,Android 常见分辨率 —— mdpi、hdpi 、xhdpi、xxhdpi
  6. java-日历记事本
  7. 网络攻防闯关练习-www.hackthissite.org
  8. 立体车库控制系统设计与研究
  9. MT4插件开发简介(开发思路)
  10. 服务器物理地址能改吗,两种修改网卡物理地址的秘技