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 集合的 Predicate
   public 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 是什么?

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐