当前位置: 首页 > 工具软件 > jpa-spec > 使用案例 >

SpringBoot:整合JPA-Specifications动态查询:

鲜于念
2023-12-01

        有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询。相比JPQL,其优势是类型安全,更加的面向对象。

JpaSpecificationExecutor接口的方法有:


    Optional<T> findOne(@Nullable Specification<T> spec);

    List<T> findAll(@Nullable Specification<T> spec);

    Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable);

    List<T> findAll(@Nullable Specification<T> spec, Sort sort);

    long count(@Nullable Specification<T> spec);

    boolean exists(Specification<T> spec);

核心参数是 Specification接口 可以采用内部类的方式或lambda表达式来创建。

自定义查询条件
            1.实现Specification接口(提供泛型:查询的对象类型)
              2.实现toPredicate方法构造查询条件)
               3.需要借助方法参数中的两个参数(
                  root:获取需要查询的对象属性
                  CriteriaBuilder:构造查询条件的,内部封装了很多的查询条件(模糊匹配,精准匹配))

1. Optional<T> findOne(@Nullable Specification<T> spec); 条件查询

@SpringBootTest
public class Tes4 {
    @Autowired
    private CustomerDao dao;

    @Test //one
    public void show1(){
        Specification<Customer> sp = (Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb)->{
            Path<Object> custName = root.get("custName");
            Predicate predicate = cb.equal(custName, "小王");
            return predicate;

        };
        Optional<Customer> one = dao.findOne(sp);
        System.out.println(one);

    }

2.List<T> findAll(@Nullable Specification<T> spec);

@Test //多条件查询
    public void show2(){
        Specification<Customer> sp = ( root,  query, cb)->{
            Path<Object> custName = root.get("custName");
            Path<Object> custAddress = root.get("custAddress");

            Predicate p1 = cb.equal(custName, "小王");
            Predicate p2 = cb.equal(custAddress, "吉祥村");
            Predicate predicate = cb.or(p1, p2);
            return predicate;
        };
        dao.findAll(sp).stream().forEach(System.out::println);

    }

3.模糊查询

 @Test //模糊
    public void show3(){
        Specification<Customer> sp = ( root,  query, cb)->{
            Path<Object> custName = root.get("custName");


            Predicate predicate   = cb.like(custName.as(String.class), "%老%");


            return predicate;
        };
        dao.findAll(sp).stream().forEach(System.out::println);

    }

4.   List<T> findAll(@Nullable Specification<T> spec, Sort sort);

 @Test //排序
    public void show4(){
        Specification<Customer> sp = ( root,  query, cb)->{
            Path<Object> custName = root.get("custName");


            Predicate predicate   = cb.like(custName.as(String.class), "%老%");


            return predicate;
        };
        Sort sort = Sort.by(Sort.Direction.DESC, "custId");
        dao.findAll(sp,sort).stream().forEach(System.out::println);

    }

5.    Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable);

@Test //分页
    public void show5(){
        Specification<Customer> sp = ( root,  query, cb)->{
            Path<Object> custName = root.get("custName");


            Predicate predicate   = cb.like(custName.as(String.class), "%老%");


            return null;
        };
        PageRequest page = PageRequest.of(1, 2);
        Page<Customer> list = dao.findAll(sp, page);
        list.getContent().stream().forEach(System.out::println);//查询结果
        System.out.println(list.getTotalElements()+"总数");
        System.out.println(list.getTotalPages()+"总页数");

    }


         

 类似资料: