全面解析JPA 仓库repository中的findAll()方法

网友投稿 595 2022-08-26


全面解析JPA 仓库repository中的findAll()方法

目录解析JPA仓库repository的findAll()方法源码YsCuUBpzgetQuery(spec,pageable)方法作用1.其中getDomainClass()作用2.执行getQuery方法执行查询语句,返回结果集(不做详细分析)jpaRepository的findOne正确写法和findAll

解析JPA仓库repository的findAll()方法

源码

Page findAll(@Nullable Specification spec, Pageable pageable);

(1) Specification spec 对象

(2) Pageable pageable 对象

下面是findAll()实现类

public Page findAll(@Nullable Specification spec, Pageable pageable) {

//参数spec只是一个实例,没有查询条件

TypedQuery query = getQuery(spec, pageable);

return isUnpaged(pageable) ? new PageImpl(query.getResultList())

: readPage(query, getDomainClass(), pageable, spec);

}

getQuery(spec,pageable)方法作用

返回一个指定操作表,指定返回项,指定排序方式,指定查询条件的query对象

1.其中getDomainClass()作用

returns the actual domain class type. 也就是数据表对应的实体类

protected TypedQuery getQuery(@Nullable Specification spec, Pageable pageable) {

Sort sort = pageable.isPaged() ? pageable.getSort() : Sort.unsorted();

return getQuery(spec, getDomainClass(), sYsCuUBpzort);

}

2.执行getQuery方法

protected TypedQuery getQuery(@Nullable Specification spec, Class domainClass, Sort sort) {

CriteriaBuilder builder = em.getCriteriaBuilder();

CriteriaQuery query = builder.createQuery(domainClass);

Root 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 Root applySpecificationToCriteria(@Nullable Specification spec, Class domainClass,CriteriaQuery query) {

Assert.notNull(domainClass, "Domain class must not be null!");

Assert.notNull(query, "CriteriaQuery must not be null!");

Root 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(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 YsCuUBpzorder 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 example = Example.of(user);

Optional one = userRepository.findOne(example);

return one.get();

}

@GetMapping("/user/all")

public List getAll() {

List all = userRepository.findAll();

System.out.println(all);

return all;

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:对pytest.mark.usefixtures的理解(pytest-allure)
下一篇:解决:ImportError while loading conftest 'e:\virtual_workshop\app_autotest\testcases\conftest.py
相关文章

 发表评论

暂时没有评论,来抢沙发吧~