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

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);

> Predicate greaterThan(Expression var1, Y var2);

> Predicate greaterThanOrEqualTo(Expression var1, Y var2);

> Predicate lessThan(Expression var1, Y var2);

> Predicate lessThanOrEqualTo(Expression var1, Y var2);

> Predicate between(Expression 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);
}

到此,已经可以实现对数据的多种复杂条件检索,分页,排序了!!!

你可能感兴趣的:(SpringCloud)