当前位置 > it书童 > java > 正文

Specifications动态查询

java it书童 2020-11-19 17:38:26 0赞 0踩 35阅读 0评论

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

对于JpaSpecificationExecutor,这个接口基本是围绕着Specification接口来定义的。我们可以简单的理解为,Specification构造的就是查询条件。

单条件查询

@Test
public void testSpec1() {
    Specification<Customer> spec = new Specification<Customer>() {
        @Override
        public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
            // 获取比较的属性
            Path<Object> custName = root.get("custName");
            // 构造查询条件
            return criteriaBuilder.equal(custName, "孙悟空");
        }
    };
    Customer customer = customerDao.findOne(spec);
    System.out.println(customer);
}

多条件查询

@Test
public void testSpec2() {
    Specification<Customer> spec = new Specification<Customer>() {
        @Override
        public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
            Path<Object> custName = root.get("custName");
            Path<Object> custIndustry = root.get("custIndustry");

            // 精准匹配查询
            Predicate p1 = criteriaBuilder.equal(custName, "卡卡罗特");
            Predicate p2 = criteriaBuilder.equal(custIndustry, "保卫地球");
            // 将多个查询条件组合在一起
            Predicate and = criteriaBuilder.and(p1, p2);
            return and;
        }
    };
    Customer customer = customerDao.findOne(spec);
    System.out.println(customer);
}

指定排序

@Test
public void testSpec3() {
    Specification<Customer> spec = new Specification<Customer>() {
        @Override
        public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
            Path<Object> custName = root.get("custName");
            // equal 可直接得到 path 对象,gt, lt, ge, le, like 需要指定参数类型,再进行比较
            return criteriaBuilder.like(custName.as(String.class), "孙%");
        }
    };
    Sort sort = new Sort(Sort.Direction.DESC, "custId");
    List<Customer> list = customerDao.findAll(spec, sort);
    for (Customer customer : list) {
        System.out.println(customer);
    }
}

分页

@Test
public void testSpec4() {
    // PageRequest 是 Pageable 的实现类
    Pageable pageable = new PageRequest(0, 2);
    // 分页查询
    Page<Customer> page = customerDao.findAll(null, pageable);
    System.out.println(page.getContent());
    System.out.println(page.getTotalElements());
    System.out.println(page.getTotalPages());
}

源码 javaDemo 1358a7c

关于我
一个文科出身的程序员,追求做个有趣的人,传播有价值的知识,微信公众号主要分享读书思考心得,不会有代码类文章,非程序员的同学请放心订阅
转载须注明出处:https://www.itshutong.com/articles/833