1. JpaSpecificationExecutor
在继承JpaRepository
,和JpaSpecificationExecutor
接口后,我们就可以使用接口中定义的方法进行查询,JpaRepository
里面定义了基本操作,而JpaSpecificationExecutor
则用于复杂查询(分页等查询操作)
2. 动态查询
有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA
中可以通过JpaSpecificationExecutor
接口查询。相比JPQL
,其优势是类型安全,更加的面向对象
/**
* JpaSpecificationExecutor中定义的方法
**/
public interface JpaSpecificationExecutor<T> {
//根据条件查询一个对象
T findOne(Specification<T> spec);
//根据条件查询集合
List<T> findAll(Specification<T> spec);
//根据条件分页查询
Page<T> findAll(Specification<T> spec, Pageable pageable);
//排序查询查询
List<T> findAll(Specification<T> spec, Sort sort);
//统计查询
long count(Specification<T> spec);
}
Specification
对于JpaSpecificationExecutor
,这个接口基本是围绕着Specification接口来定义的。我们可以简单的理解为,Specification
构造的就是查询条件
Specification
接口中只定义了这一个方法
//构造查询条件
/**
* Root :Root接口,代表查询的根对象,查询的任何属性都可以通过根对象中获取
* CriteriaQuery:代表一个顶层查询对象,用来自定义查询
* CriteriaBuilder :用来构建查询,此对象里有很多条件方法
**/
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
2.1 使用Specifications
完成条件查询
//依赖注入customerDao
@Autowired
private CustomerDao customerDao;
@Test
public void testSpecifications() {
//使用匿名内部类的方式,创建一个Specification的实现类,并实现toPredicate方法
Specification <Customer> spec = new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//cb:构建查询,添加查询方式 like:模糊匹配
//root:从实体Customer对象中按照custName属性进行查询
Path<Object> custName = root.get("custName");
return cb.equal(custName,"minifull");
}
};
Customer customer = customerDao.findOne(spec);
System.out.println(customer);
}