全面解析JPA?倉庫repository中的findAll()方法
解析JPA倉庫repository的findAll()方法
源碼
Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable);
(1) Specification spec 對象
(2) Pageable pageable 對象
下面是findAll()實現(xiàn)類
public Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable) { //參數(shù)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. 也就是數(shù)據(jù)表對應的實體類
protected TypedQuery<T> getQuery(@Nullable Specification<T> spec, Pageable pageable) { Sort sort = pageable.isPaged() ? pageable.getSort() : Sort.unsorted(); return getQuery(spec, getDomainClass(), sort); }
2.執(zhí)行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動態(tài)構(gòu)造查詢)
CriteriaBuilder
:可以用于創(chuàng)建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實例調(diào)用Spec類中的toPredicate(),獲取查詢條件。
where()源碼翻譯:
query.where(predicate)作用,根據(jù)predicate(查詢條件的集合)修改query限制查詢結(jié)果(如果之前有條件限制,會自動替換),如果此次沒有添加任何限制,之前的條件限制會被移除(也就是說,條件限制會覆蓋),這里的where()重寫了AbstractQuery接口中where(),predicate條件可以為空也可以是多個,返回結(jié)果是the modified query
2.2 回到getQuery方法中
query.select(root); if (sort.isSorted()) { query.orderBy(toOrders(sort, root, builder)); }
query.select()
:指定要在查詢結(jié)果中返回的項(覆蓋,若之前有所指定,則覆蓋),這里指定返回項是表對應的實體類,返回結(jié)果是the modified queryquery.orderBy()
:修改排序規(guī)則,返回結(jié)果也是the modified query,這里不對 toOrders過多的即使
return applyRepositoryMethodMetadata(em.createQuery(query));
em.createQuery(query)
:創(chuàng)建TypedQuery 實例,用來執(zhí)行executing a criteria query
執(zhí)行查詢語句,返回結(jié)果集(不做詳細分析)
return isUnpaged(pageable) ? new PageImpl<T>(query.getResultList()) : readPage(query, getDomainClass(), pageable, spec);
query.getResultList()
:返回查詢結(jié)果(相當于hibernate中l(wèi)ist()方法執(zhí)行hql,返回結(jié)果)getResultList()
:方法會調(diào)用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; }
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
如何使用MyBatis Plus實現(xiàn)數(shù)據(jù)庫curd操作
MyBatis-Plus是一個MyBatis 的增強工具,在MyBatis,的基礎上只做增強不做改變,為簡化開發(fā)、提高效率而生。 這篇文章主要介紹了MyBatis Plus實現(xiàn)數(shù)據(jù)庫curd操作,需要的朋友可以參考下2021-09-09spring,mybatis事務管理配置與@Transactional注解使用詳解
這篇文章主要介紹了spring,mybatis事務管理配置與@Transactional注解使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07springboot之security?FilterSecurityInterceptor的使用要點記錄
這篇文章主要介紹了springboot之security?FilterSecurityInterceptor的使用要點記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12關于Controller層和Service層的類報錯問題及解決方案
這篇文章主要介紹了關于Controller層和Service層的類報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02