Spring JPA简单分页查询以及复杂查询(范围查询,模糊查询等)

本文介绍如何使用Spring JPA实现分页查询及精确检索,并通过JpaSpecificationExecutor实现更复杂的业务需求,包括时间范围和模糊查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2019年01月23日 01:34:50 _隔壁小黑 阅读数 1509更多
分类专栏: SpringCloud
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.youkuaiyun.com/m18362894610/article/details/86603732
Spring JPA简单分页查询通过继承JpaRepository接口实现,该接口提供以下几种查询方法

//查询所有
List findAll();

//查询所有+排序
List findAll(Sort var1);

//查询所有,Example可以筛选查询条件,但仅限于精确查询
List findAll(Example var1);

//查询所有+排序,Example可以筛选查询条件,但仅限于精确查询
List findAll(Example var1, Sort var2);

//分页查询
Page findAll(Pageable var1);

//分页查询,Example可以筛选查询条件,但仅限于精确查询
Page findAll(Example var1, Pageable var2);
这里以一个Role对象作为例子:

package com.cwh.chl.manager.system.entity;

import javax.persistence.*;

/**

  • 职位,角色
    /
    @Entity
    @Table(name = “role”)
    public class Role {
    @Id
    @Column
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;
    /
    *

    • 职位名称
      /
      @Column
      private String name;
      /
      *
    • 岗位数量
      /
      @Column
      private Integer num;
      /
      *
    • 是否总后台职位,0:不是,1:是,2:门店区域经理
      /
      @Column
      private Integer is_manager;
      /
      *
    • 门店id,若为总后台或区域经理,此参数为0
      */
      @Column
      private Integer store_id;

    public Integer getStore_id() {
    return store_id;
    }

    public void setStore_id(Integer store_id) {
    this.store_id = store_id;
    }

    public Integer getIs_manager() {
    return is_manager;
    }

    public void setIs_manager(Integer is_manager) {
    this.is_manager = is_manager;
    }

    public Integer getId() {
    return id;
    }

    public void setId(Integer id) {
    this.id = id;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public Integer getNum() {
    return num;
    }

    public void setNum(Integer num) {
    this.num = num;
    }
    }
    其中在简单查询中,最常用的为最有一种,分页+精确查询,Pageable接口通过实现getPageNumber,getPageSize,getSort三个方法可以同时配置分页参数以及排序参数,通常我们传入Pageable的实现类PageRequest作为Pageable传参。示例代码如下:

Role role = new Role();
role.setId(1);
Example example = Example.of(role);
PageRequest pageRequest = PageRequest.of(pageNum - 1,pageSize);
Page page = roleRepository.findAll(example,pageRequest);
Example.of(role)为创建一个Example对象,传入的role对象就是需要检索的条件,JPA会将role对象中不为空的参数作为检索条件,所以这里需要注意Role参数不要定义基本数据类型。到此Role表可以做分页查询以及精确检索。

如果还要对Role进行id降序显示的话,还可以在PageRequest对象中配置排序

Role role = new Role();
role.setId(1);
Example example = Example.of(role);

//按照id降序排列
Sort.Order order = new Sort.Order(Sort.Direction.DESC,“id”);
Sort sort = Sort.by(order);
//查询
PageRequest pageRequest = PageRequest.of(pageNum - 1,pageSize,sort);
Page page = roleRepository.findAll(example,pageRequest);
但是我们做业务通常需要更加复杂的检索方式,例如订单管理,需要知道某个时间段的订单有哪些,商品管理需要模糊查询出匹配关键字的商品,此时JpaRepository接口已经不能满足这些复杂业务需求,可有通过继承JpaSpecificationExecutor实现复杂查询+分页+排序,JpaSpecificationExecutor提供的查询方法如下:

//通过Specification对查询数据进行筛选,返回筛选后的所有数据
List findAll(@Nullable Specification var1);

//分页查询,Specification可对查询数据进行筛选
Page findAll(@Nullable Specification var1, Pageable var2);

//通过Specification对查询数据进行筛选,返回筛选后的所有数据根据Sort排序
List findAll(@Nullable Specification var1, Sort var2);
这三个接口中Specification参数就是传入的检索条件,与PageRequest功能一致,不同的是Specification需要我们实现它的toPredicate自行配置搜索条件,接口如下:

public Predicate toPredicate(Root root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder);
这里CriteriaBuilder对象是用来拼接检索条件的,这个方法返回一个Predicate,而Predicate可以通过CriteriaBuilder生成,提供部分方法如下:

Predicate equal(Expression<?> var1, Object var2);

Predicate notEqual(Expression<?> var1, Object var2);

<Y extends Comparable<? super Y>> Predicate greaterThan(Expression<? extends Y> var1, Y var2);

<Y extends Comparable<? super Y>> Predicate greaterThanOrEqualTo(Expression<? extends Y> var1, Y var2);

<Y extends Comparable<? super Y>> Predicate lessThan(Expression<? extends Y> var1, Y var2);

<Y extends Comparable<? super Y>> Predicate lessThanOrEqualTo(Expression<? extends Y> var1, Y var2);

<Y extends Comparable<? super Y>> Predicate between(Expression<? extends Y> var1, Y var2, Y var3);

Predicate like(Expression var1, String var2);
这些方法根据命名即可看出功能,分别是相等,不想等,大于,大于等于,小于,小于等于,区间,模糊匹配

我们以模糊匹配为例,若要检索Role对象中名称带‘店’的所有Role

public Predicate toPredicate(Root root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
return criteriaBuilder.like(root.get(“name”).as(String.class),"%店%");
}
但是我们在正常业务中,有时可能不仅仅一个检索条件,比如我们想模糊匹配名称为店的数据同时,store_id是1的数据,此时CriteriaBuilder还提供了一种拼接方式

Predicate and(Predicate… var1);

Predicate or(Predicate… var1);
通过and以及or对两个条件进行拼接,返回一个新的Predicate对象:

public Predicate toPredicate(Root root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Predicate predicate = criteriaBuilder.like(root.get(“name”).as(String.class),"%店%");
Predicate predicate2 = criteriaBuilder.equals(root.get(“store_id”).as(String.class),“1”);
return criteriaBuilder.and(predicate,predicate2);
}
到此,已经可以实现对数据的多种复杂条件检索,分页,排序了!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值