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 extends Y> var1, Y var2);
> Predicate greaterThanOrEqualTo(Expression extends Y> var1, Y var2);
> Predicate lessThan(Expression extends Y> var1, Y var2);
> Predicate lessThanOrEqualTo(Expression extends Y> var1, Y var2);
> 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);
}
到此,已经可以实现对数据的多种复杂条件检索,分页,排序了!!!