一)单条件查询
JpaSpecificationExecutor接口的使用一般要和Repository体系的接口一起使用
JpaSpecificationExecutor接口源码
public interface JpaSpecificationExecutor<T> {
T findOne(Specification<T> var1); //查询一个
List<T> findAll(Specification<T> var1);//条件产讯
Page<T> findAll(Specification<T> var1, Pageable var2);//分页查询
List<T> findAll(Specification<T> var1, Sort var2);//排序查询
long count(Specification<T> var1);//计数查询
}
原因:
在讲述原理的时候Dao对象其实是注入了一个代理对象,通过继承Repository体系接口完成代理对象SimpleJpaRepository实现类对象的注入。而JpaSpecificationExecutor对象不在Repository接口体系内那么就无法完成对象注入,所以要使用JpaSpecificationExecutor对象必须要实现Repository体系接口
1.1)测试单条件查询
JpaSpecificationExecutor对象接收参数Specifcation对象该对象是一个接口,此对象的作用想当与在hibernateJPA中使用QBC查询的操作,只是使用了Specifcation对象进行了封装,简化我们的操作
Specifcation对象源码
public interface Specification<T> {
Predicate toPredicate(Root<T> var1, CriteriaQuery<?> var2, CriteriaBuilder var3);
}
单条件查询
@Test
public void test1(){
Specification spc = new Specification(){
@Override
/**
* @description:
* @param root 根参数,通过次对象获取实体对象字段进行条件的设置
* @param criteriaQuery 定义一个基本的查询
* @param criteriaBuilder 创建一个查询条件
* @return: javax.persistence.criteria.Predicate
* @author: shinelon
* @time: 2019/8/20:17:35
*/
public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
return criteriaBuilder.equal(root.get("username"),"AAA");
}
};
List<Users> list = this.userDaoFive.findAll(spc);
for (Users u :
list ) {
System.out.println(u);
}
}
结果
二)多条件查询
2.1)方式一
使用参数Predicate进行参数的设置完成将多个的条件封装成数组的形式传递给接收多个参数的方法完成多条件查询
/**
* 多条件查询使用Predicate集合进行添加条件,将数据填充到集合内
* Predicate and(Predicate... var1);接收可变形参将集合转成数组即可(可以直接使用数组)
*/
@Test
public void test3(){
Specification spc = (x,y,z)->{
ArrayList<Predicate> list = new ArrayList<>();
list.add(z.equal(x.get("username"),"AAA"));
list.add(z.equal(x.get("password"),"123"));
Predicate[] predicates = new Predicate[list.size()];
return z.and(list.toArray(predicates));
};
List<Users> list = this.userDaoFive.findAll(spc);
list.stream()
.forEach(System.out::println);
}
结果:
2.2)方式二
直接在条件查询内写入查询的条件即可SpringData 会自动的将条件进行拼接
缺点:如果出现条件较长的话会出现代码过长的问题
/**
* 多条件查询方式二
*/
@Test
public void test4(){
Specification spc = (x,y,z)->z.and(z.equal(x.get("username"),"AAA"),z.equal(x.get("password"),"123"));
List<Users> list = this.userDaoFive.findAll(spc);
list.stream()
.forEach(System.out::println);
}
结果
三)JpaSpecificationExecutor接口的分页查询
使用JpaSpecificationExecutor对象内的findAll方法能够进行带条件的查询
/**
* 条件分页查询 注意使用like进行分页查询的时候需要做类型转换
*/
@Test
public void test5(){
Specification<Users> spc = (x,y,z)->z.ge(x.get("userid"),2);
Page<Users> page = this.userDaoFive.findAll(spc, new PageRequest(0, 5));
page.getContent().stream().forEach(System.out::println);
}
结果
四)JpaSpecificationExecutor接口实现排序
使用JpaSpecificationExecutor对象内的findAll方法能够进行带排序的查询
/**
* 排序
*/
@Test
public void test6(){
Specification<Users> spc = (x,y,z)->z.ge(x.get("userid"),2);
List<Users> list = this.userDaoFive.findAll(spc, new Sort(Sort.Direction.DESC,"userid"));
list.stream().forEach(System.out::println);
}
五)JpaSpecificationExecutor实现分页+排序+条件
使用PageRequst的构造方法接收一个Sort类型的参数作为排序的条件
/**
* 分页加排序+条件
*/
@Test
public void test7(){
Specification<Users> spc = (x,y,z)->z.ge(x.get("userid"),2);
Page<Users> page = this.userDaoFive.findAll(spc, new PageRequest(0, 3, new Sort(Sort.Direction.DESC, "userid")));
page.getContent().stream().forEach(System.out::println);
}
结果
来源:https://blog.csdn.net/weixin_44124307/article/details/99882036