JpaSpecificationExecutor 实现原理
我们还是先通过开发工具,把关键的类添加到Diagram上面进行分析,如图:
我们通过上图可以看一下,前面介绍的几个类之间的关联关系。
SimpleJpaRepository 实现类中的关键源码如下:
/***以 findOne 为例
*/
public T findOne(Specification<T> spec) {try {return getQuery(spec, (Sort) null).getSingleResult();} catch (NoResultException e) {return null;}
}
/** 解析 Specification,利用 EntityManager 直接实现调用逻辑。
*/
protected <S extends T> TypedQuery<S> getQuery(Specification<S> spec, Class<S> domainClass, Sort sort) {CriteriaBuilder builder = em.getCriteriaBuilder();CriteriaQuery<S> query = builder.createQuery(domainClass);Root<S> root = applySpecificationToCriteria(spec, domainClass, query);query.select(root);if (sort != null) {query.orderBy(toOrders(sort, root, builder));}return applyRepositoryMethodMetadata(em.createQuery(query));
}
其实我们可以看的出来底层都是调用的 EntityManager。
与 EntityManager 的关系图
通过此图可以体会一下 Repository 和 EntityManager 的关联关系。
其实在实际项目中,我们的 Repository 可以扩展的更加优雅一点来解决后台 API 的 search 问题和如何自定义 Respository?下一篇内容将会来讲解这个问题。