JpaSpecificationExecutor 源码和 API
我们也可以通过 idea 工具详细看其用法和实现类,JpaSpecificationExecutor 是 Repository 要继承的接口,而 SimpleJpaRepository 是其默认实现。而通过源码来看其提供的 API 比较简单、明了,有如下几个方法:
public interface JpaSpecificationExecutor<T> {//根据 Specification 条件查询单个对象,注意的是,如果条件能查出来多个会报错T findOne(@Nullable Specification<T> spec);//根据 Specification 条件查询 List 结果List<T> findAll(@Nullable Specification<T> spec);//根据 Specification 条件,分页查询Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable);//根据 Specification 条件,带排序的查询结果List<T> findAll(@Nullable Specification<T> spec, Sort sort);//根据 Specification 条件,查询数量long count(@Nullable Specification<T> spec);
}
不难看出,这个接口基本是围绕着 Specification 接口来定义的。我们先来看下其源码:
仔细看看图,就会发现 Specifications 的接口实现类就三个。
/*** Specifications 是 Spring Data JPA 对 Specification 的聚合操作工具类,里面有以下四个方法:
*/
@Deprecated //已经不推荐使用了,我们可以用 Specification 来代替,如上图。
public class Specifications<T> implements Specification<T>, Serializable {private final Specification<T> spec;//构造方法私有化,只能通过 where/not 创建 Specifications 对象。private Specifications(Specification<T> spec) {this.spec = spec;}//创建 where 后面的 Predicate 集合public static <T> Specifications<T> where(Specification<T> spec) {return new Specifications<T>(spec);}//创建 not 集合的 Predicatepublic static <T> Specifications<T> not(Specification<T> spec) {return new Specifications<T>(new NegatedSpecification<T>(spec));}//Specification 的 and 关系集合public Specifications<T> and(Specification<T> other) {return new Specifications<T>(new ComposedSpecification<T>(spec, other, AND));}//Specification 的 or 关系集合public Specifications<T> or(Specification<T> other) {return new Specifications<T>(new ComposedSpecification<T>(spec, other, OR));}
......
}
而如果查看 Specifications 源码的话就会发现,其已经将来要被删除了,已经不推荐使用了,而另外两个都是局部私有的,所以真正关注的就是 Specification 接口中如下一个接口方法:
public interface Specification<T> {Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
}
从这里可以看出,每个调用的地方都需要,创建 Specification 的实现类,而 JpaSpecificationExecutor 是针对 Criteria API 进行了 predicate 标准封装,帮我们封装了通过 EntityManager 的查询和使用细节,使操作 Criteria 更加便利了一些。所以我们要掌握一下 Predicate、Root、CriteriaQuery、CriteriaBuilder 是什么?