欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 前端技术 > javascript >内容正文

javascript

SpringData JPA条件查询、排序、分页查询

发布时间:2025/3/20 javascript 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 SpringData JPA条件查询、排序、分页查询 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

前言

在刚开始学习的时候,在dao的定义的接口需要继承JpaRepository<T, ID>接口JpaSpecificationExecutor< T >接口,但是一直以来我用到的都只是JpaRepository,用于自动生成相关SQL语句简化代码。而JpaSpecificationExecutor给我的感觉就可有可无了,直到最近才发现它的用处,在此记录一波。因为是学习笔记的关系,所以里面都只是截取关键的代码进行记录。

正文

要想使用Spring Data JPA,需要在pom.xml中添加以下依赖:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.7.RELEASE</version><relativePath/> <!-- lookup parent from repository --> </parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency> <dependencies>

如前言所说,带条件的分页查询方法是被定义在JpaSpecificationExecutor接口中的,所以这里需要继承这个接口。

/*** @author Veggie* @date 2019/8/14 - 14:11*/ @Repository public interface MessageRepository extends JpaRepository<Message, Long>, JpaSpecificationExecutor<Message> { }

1. 条件查询

自定义查询条件的步骤:

  • 实现Specification< T >接口(提供泛型;查询的对象类型)
  • 实现toPredicate方法(构造查询条件)
  • 需要借助方法参数中的两个参数:
    root:获取需要查询的对象属性
    CriteriaBuilder:构造查询条件,内部封装了很多查询条件(模糊匹配,精准匹配)
  • //自定义查询条件 Specification<Message> spec = new Specification<Message>() {@Overridepublic Predicate toPredicate(Root<Message> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {//根据属性名获取查询对象的属性Path<Message> path = root.get("receiverName");//相当于 where receiverName = "Veggie", CriteriaBuilder接口中还有很多查询条件,建议看源码Predicate equal = criteriaBuilder.equal(path, "Veggie");return equal;}} //进行条件查询,findAll()方法中的参数即为条件 List<Message> result = MessageRepository.findAll(spec);

    当查询条件用到gt, ge, lt, le, like(分别表示>, >=, <, <=,模糊查询)时,需要表明查询对象属性的类别,如下所示:

    //查询用户名以"V"开头的用户 Predicate like = criteriaBuilder.like(path.as(String.class), "V%");

    2. 排序

    排序用到的是一个Sort类,它是查询的排序选项(看源码,有介绍)
    它初始化是用到的参数第一个参数:
    Sort.Direction.DESC表示降序
    Sort.Direction.ASC表示升序

    随后的参数就是要排序的属性列表,可以有多个参数,也可以直接用List传,但是至少传入一个属性。

    Sort sort = new Sort(Sort.Direction.DESC, "id"); //sort作为findAll()方法中的参数,查询得到得到的结果是经过排序的 List<Message> result = MessageRepository.findAll(sort);

    3.分页查询

    分页需要设置分页参数类Pageable,初始化主要是有两个参数:第一个是查询的页码(下标从0开始),第二个是每页查询的条数,比如说结果有55条,如果每页查询10条,结果就会被分成6页。也可以添加
    注意:原来用到的new PageRequest()已经过时,现在用PageRequest.of()来实现。

    Page接口是封装为Spring Data Jpa 内部的page bean,它的常用方法如下:

    //获取总页数 int getTotalPages(); //获取总记录数 long getTotalElements(); //获取列表数据 List<T> getContent();

    分页查询的代码如下:

    //设置分页参数 Pageable pageable = PageRequest.of(05); //分页查询 Page<Message> page = MessageRepository.findAll(pageable);

    4. 完整的方法代码

    完整的代码是以上三个知识点的集合,是带条件的分页查询,查询得到的结果按id号降序排序。

    @RequestMapping(path = "/page")public List<Message> queryPage(@RequestBody Map<String, Object> params) {/*** 自定义查询条件* 1. 实现Specification接口(提供泛型;查询的对象类型)* 2. 实现toPredicate方法(构造查询条件)* 3. 需要借助方法参数中的两个参数(* root:获取需要查询的对象属性* CriteriaBuilder:构造查询条件,内部封装了很多查询条件(模糊匹配,精准匹配)*/Specification<Message> spec = new Specification<Message>() {@Overridepublic Predicate toPredicate(Root<Message> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {Path<Message> path = root.get("receiverName");Predicate equal = criteriaBuilder.equal(path, "Veggie");return equal;}};Integer pageNo = Integer.valueOf((String) params.get("pageNo"));Integer pageSize = Integer.valueOf((String)params.get("pageSize"));/*** 添加排序Sort* Sort.Direction.DESC表示降序* Sort.Direction.ASC表示升序* properties是指实体类的属性名(不是字段名)*/Sort sort = new Sort(Sort.Direction.ASC, "id");/*** 分页参数Pageable* 参数1:查询的页码* 参数2:每页查询的条数* 参数3:查询结果的排序规则(可选*/Pageable pageable = PageRequest.of(pageNo, pageSize, sort); //原来的new PageRequest()已经过时/*** 分页查询* 参数1:查询条件Specification* 参数2:分页参数Pageable*/Page<Message> page = MessageRepository.findAll(spec, pageable);return page.getContent();}

    感悟

    既然都写博客了,顺带记录最近学习以及和大佬交谈的感悟:

  • 理解概念:在学习的时候,不能仅仅想着敲代码,要多关注一些相关概念的理解,就比如说JPA、 Hibernate和SpringData JPA各自的基本概念,他们之间有什么关系之类的。
  • 多看源码:我具体也说不上来,就本能的感觉这个很重要。有时候一看源码,可以理解之前想了很久都没有想明白的问题。其次,看某个类或接口的源码时,还可以了解到这个类可以提供什么方法(一般都会有英文注释的)。
  • 思维导图:就像看书一定要想看目录,学习新的内容应该先做个思维导图。它以让我们对一样东西的总体有比较直观、系统的认识,可以让学习的思路变得清晰,可以避免浪费一些不必要 的时间。
  • 多做笔记:连dalao都记不住之前学过的东西,何况我等凡夫俗子。做笔记不仅可以备忘,避免踩同样的坑,还可以加深对该部分知识的理解。
  • 参考资料

  • https://www.bilibili.com/video/av53910024/?p=65
  • 总结

    以上是生活随笔为你收集整理的SpringData JPA条件查询、排序、分页查询的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。