jpa使用Specification动态查询和分页
Specification核心方法
Predicate toPredicate(Root
- Root:代表查询的根对象 即实体
- CriteriaQuery : 顶层查询对象****,用于自定义查询方式 基本不用
- CriteriaBuilder:查询构造器,封装了很多的查询条件
案例:
@Test
public void testSpecification(){
//查询菜单名包含 测试 和菜单id=1212的数据
Specification<SysMenu> specification=(root,query,buidler)->{
//获取比较对象 从root中获取
Path<String> menuName = root.get("menuName");
//比较值
Predicate pre1 = buidler.like(menuName, "测试%");
//获取比较对象 从root中获取
Path<Long> id = root.get("menuId");
//比较值
Predicate pre2 = buidler.equal(id, 1212l);
//组装对象 使用buidler
Predicate and = buidler.or(pre1,pre2);
return and;
};
//构建排序
Sort sort=Sort.by("menuId").descending();
List<SysMenu> menuList= dao.findAll(specification,sort);
menuList.forEach(p-> System.out.println(p));
//分页
Pageable pageable=PageRequest.of(1,1,sort);
Page<SysMenu> all = dao.findAll(specification, pageable);
System.out.println(all.getTotalElements());
System.out.println(all.getTotalPages());
System.out.println(all.getContent());
}
组合多条件复杂查询
public void test(){
//第一个Specification定义了两个or的equal组合
Specification<Dept> s1 = (root, criteriaQuery, criteriaBuilder) -> {
Predicate p1 = criteriaBuilder.equal(root.get("deptno"), "20");
Predicate p2 = criteriaBuilder.equal(root.get("deptno"), "30");
return criteriaBuilder.or(p1, p2);
};
//第二个Specification定义了两个or的like组合
Specification<Dept> s2 = (root, criteriaQuery, criteriaBuilder) -> {
Predicate p1 = criteriaBuilder.like(root.get("dname"), "%S%");
Predicate p2 = criteriaBuilder.like(root.get("loc"), "AS%");
return criteriaBuilder.or(p1, p2);
};
//通过Specification将两个Specification连接起来,第一个条件加where,第二个是and
List<Dept> depts = deptDao.findAll(Specification.where(s1).and(s2));
depts.forEach(System.out::println);
}