全面解析JPA 仓库repository中的findAll()方法
解析JPA仓库repository的findAll()方法
源码
Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable);
(1) Specification spec 对象
(2) Pageable pageable 对象
下面是findAll()实现类
public Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable) {
//参数spec只是一个实例,没有查询条件
TypedQuery<T> query = getQuery(spec, pageable);
return isUnpaged(pageable) ? new PageImpl<T>(query.getResultList())
: readPage(query, getDomainClass(), pageable, spec);
}
getQuery(spec,pageable)方法作用
返回一个指定操作表,指定返回项,指定排序方式,指定查询条件的query对象
1.其中getDomainClass()作用
returns the actual domain class type. 也就是数据表对应的实体类
protected TypedQuery<T> getQuery(@Nullable Specification<T> spec, Pageable pageable) {
Sort sort = pageable.isPaged() ? pageable.getSort() : Sort.unsorted();
return getQuery(spec, getDomainClass(), sort);
}
2.执行getQuery方法
protected <S extends T> TypedQuery<S> getQuery(@Nullable 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.isSorted()) {
query.orderBy(toOrders(sort, root, builder));
}
return applyRepositoryMethodMetadata(em.createQuery(query));
}
其中em是EntityManager对象,用来获取CriteriaBuilder 实例(参考链接CriteriaBuilder动态构造查询)
CriteriaBuilder
:可以用于创建CriteriaQuery、CriteriaUpdate和CriteriaDelete等createQuery
:hibernate的SQL操作方法,用来生成一个基于 HQL 查询字符串的 Query 对象,domainClass指的是表对应的实体类
2.1 applySpecificationToCriteria(…)方法:
将Specification中生成的Predicate应用于Criteria
private <S, U extends T> Root<U> applySpecificationToCriteria(@Nullable Specification<U> spec, Class<U> domainClass,CriteriaQuery<S> query) {
Assert.notNull(domainClass, "Domain class must not be null!");
Assert.notNull(query, "CriteriaQuery must not be null!");
Root<U> root = query.from(domainClass);
if (spec == null) {
return root;
}
CriteriaBuilder builder = em.getCriteriaBuilder();
Predicate predicate = spec.toPredicate(root, query, builder);
if (predicate != null) {
query.where(predicate);
}
return root;
}
spec.toPredicate(…)方法,是spec实例调用Spec类中的toPredicate(),获取查询条件。
where()源码翻译:
query.where(predicate)作用,根据predicate(查询条件的集合)修改query限制查询结果(如果之前有条件限制,会自动替换),如果此次没有添加任何限制,之前的条件限制会被移除(也就是说,条件限制会覆盖),这里的where()重写了AbstractQuery接口中where(),predicate条件可以为空也可以是多个,返回结果是the modified query
2.2 回到getQuery方法中
query.select(root);
if (sort.isSorted()) {
query.orderBy(toOrders(sort, root, builder));
}
query.select()
:指定要在查询结果中返回的项(覆盖,若之前有所指定,则覆盖),这里指定返回项是表对应的实体类,返回结果是the modified queryquery.orderBy()
:修改排序规则,返回结果也是the modified query,这里不对 toOrders过多的即使
return applyRepositoryMethodMetadata(em.createQuery(query));
em.createQuery(query)
:创建TypedQuery 实例,用来执行executing a criteria query
执行查询语句,返回结果集(不做详细分析)
return isUnpaged(pageable) ? new PageImpl<T>(query.getResultList())
: readPage(query, getDomainClass(), pageable, spec);
query.getResultList()
:返回查询结果(相当于hibernate中list()方法执行hql,返回结果)getResultList()
:方法会调用doList()方法
这个方法中会生成SQL语句expandeQuery:
select generatedAlias0 from Students as generatedAlias0 where 1=1 order by generatedAlias0.studentAge desc
jpa Repository的findOne正确写法和findAll
@GetMapping("/user/{id}")
public User getUser(@PathVariable("id") Integer id) {
User user = new User();
user.setId(id);
Example<User> example = Example.of(user);
Optional<User> one = userRepository.findOne(example);
return one.get();
}
@GetMapping("/user/all")
public List<User> getAll() {
List<User> all = userRepository.findAll();
System.out.println(all);
return all;
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341