JpaSpecificationExecutor 接口
一、JpaSpecificationExecutor 接口介绍
1、该接口主要提供了多条件查询的支持,并且可以在查询中添加分页与排序。(之前 PagingAndSortingRepository 接口进行分页和排序的前提条件是 findAll 查询全部。)
2、JpaSpecificationExecutor 是单独存在的、跟之前的继承关系扯不上。独立公关人。
3、一般开发中,都是将 JpaSpecificationExecutor 接口与 JpaRepository 接口配合使用来完成开发。
二、JpaSpecificationExecutor 接口使用
2.1 编写 /src/main/java/cn/yangdh/dao/UsersRepositorySpecification.java 接口
package cn.yangdh.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import cn.yangdh.pojo.Users;
/**
* 该接口 继承了两个接口:JpaRepository接口 、JpaSpecificationExecutor接口
*
* @author *****
*
*/
public interface UsersRepositorySpecification extends JpaRepository<Users, Integer> ,JpaSpecificationExecutor<Users>{
}
2.2 编写测试 /src/test/java/cn/yangdh/test/UsersRepositoryTest.java
单条件查询:
//注入 JPASpecificationExecutor 接口
@Autowired
private UsersRepositorySpecification usersRepositorySpecification;
/*
* JpaSpecificationExecutor 接口
*
* 单条件查询 测试
* demo: where name = "许知远"
*/
@Test
public void testJpaSpecificationExecutor1(){
/*
* Specification<Users> 该对象用于封装要查询的条件的。
*
*/
Specification<Users> spec = new Specification<Users>() {
/*
* Predicate :该对象封装了单个的查询条件、即一个Predicate 就是一个查询条件。
* 参数Root<Users> 查询对象的属性的封装
* 参数CriteriaQuery<?> 封装了要执行的查询中的各个部分的信息(eg:select from order by)
* 参数CriteriaBuilde 查询条件的构造器、帮助我们定义不同的查询条件的。
*/
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
// eg:where name = "许知远"
// 做相等判断
/*
* 参数一:查询的条件的属性、但是需要从root里去取出
* 参数二:条件的值
* 单条件查询:查询name为许知远的Users
*/
Predicate pre = cb.equal(root.get("name"), "许知远");//需要从root里去取出
return pre;
}
};
List<Users> list = this.usersRepositorySpecification.findAll(spec);
for (Users users : list) {
System.out.println(users);
}
}
多条件查询(方式一、即创建 Predicate 集合 ):
/*
* JpaSpecificationExecutor 接口
*
* 多条件查询 测试
* 区别在于 toPredicate 方法内不同、即创建 Predicate 集合
* demo: where name = "许知远" and age = 43; 多条件指的是这个意思,比如and、or等
*/
@Test
public void testJpaSpecificationExecutor2(){
/*
* Specification<Users> 该对象用于封装要查询的条件的。
*
*/
Specification<Users> spec = new Specification<Users>() {
/*
* Predicate :该对象封装了单个的查询条件、即一个Predicate 就是一个查询条件。
* 参数Root<Users> 查询对象的属性的封装
* 参数CriteriaQuery<?> 封装了要执行的查询中的各个部分的信息(eg:select from order by)
* 参数CriteriaBuilde 查询条件的构造器、帮助我们定义不同的查询条件的。
*/
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//eg: where name = "许知远" and age = 43;
List<Predicate> list = new ArrayList<Predicate>();
//两个 Predicate
list.add(cb.equal(root.get("name"), "许知远"));
list.add(cb.equal(root.get("age"), 43));
//给定这两个条件的关系
Predicate[] preArr = new Predicate[list.size()]; //构建数组
Predicate pre = cb.and(list.toArray(preArr));//and方法参数为 Predicate的数组、同时list 转换成数组 内部参数也为Predicate 数组
return pre;
}
};
List<Users> list = this.usersRepositorySpecification.findAll(spec);
for (Users users : list) {
System.out.println(users);
}
}
多条件查询(方式二、 不用list集合,and 或 or …等方法的参数列表里 直接按数组的形式放进去即可、用逗号隔开):
/*
* JpaSpecificationExecutor 接口
*
* 多条件查询 测试 方式二
* demo: where name = "许知远" and age = 43 or age = 0;
* 即 where ((name = "许知远" and age = 43) or age = 0);
*/
@Test
public void testJpaSpecificationExecutor3(){
/*
* Specification<Users> 该对象用于封装要查询的条件的。
*
*/
Specification<Users> spec = new Specification<Users>() {
/*
* Predicate :该对象封装了单个的查询条件、即一个Predicate 就是一个查询条件。
* 参数Root<Users> 查询对象的属性的封装
* 参数CriteriaQuery<?> 封装了要执行的查询中的各个部分的信息(eg:select from order by)
* 参数CriteriaBuilde 查询条件的构造器、帮助我们定义不同的查询条件的。
*/
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//如果是 and 查询
//return cb.and(cb.equal(root.get("name"), "许知远"), cb.equal(root.get("age"), 43));
//如果是 or 查询
//return cb.or(cb.equal(root.get("name"), "许知远"), cb.equal(root.get("age"), 43));
//如果既有 and 又有 or 查询(原则: 先考虑and 、再考虑or)
//name = "许知远" and age = 43 or age = 0 (说明:and优先级高于 or)
return cb.or(cb.and(cb.equal(root.get("name"), "许知远"), cb.equal(root.get("age"), 43) ), cb.equal(root.get("age"), 0));
}
};
List<Users> list = this.usersRepositorySpecification.findAll(spec);
for (Users users : list) {
System.out.println(users);
}
}