Spring Data JPA之分頁查詢


一、普通:分頁+排序

因為PagingAndSortingRepository,我們總是可以傳入Sort和Pageable對查詢結果進行排序和分頁(derived query、example查詢和@Query查詢都支持)。

// 當查詢方法中有多個參數的時候,Pageable/Sort建議做為最后一個參數傳入

@Query("select u from User u")
Page<User> findALL(Pageable pageable);

Page<User> findByNickName(String nickName, Pageable pageable);

// 可以返回Page<T>對象,也可以返回List<T>對象

由於JPA(JPQL)不支持Limit,請采用其他方法實現limit需求,https://stackoverflow.com/questions/44565820/what-is-the-limit-clause-alternative-in-jpql 

二、單表:分頁 + 排序 + 動態查詢

  1. repository繼承JpaSpecificationExecutor<T>接口;
    • 最終調用Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable)實現“分頁+排序”功能
  2. 構造Specification<T> spec;
    • 搜索Specification能得到很多網頁結果
      interface Specification<T> {
          Predicate toPredicate(Root<T> root, CriteriaQuery query, CriteriaBuilder cb);
      }
  3. 構造Pageable pageable,
    • Pageable是可以帶Sort的
      Pageable sortedByName = 
        PageRequest.of(0, 3, Sort.by("name"));
       
      Pageable sortedByPriceDesc = 
        PageRequest.of(0, 3, Sort.by("price").descending());
       
      Pageable sortedByPriceDescNameAsc = 
        PageRequest.of(0, 5, Sort.by("price").descending().and(Sort.by("name")));
  4. 等待補充

三、多表:分頁 + 排序 + 動態查詢

  1. 選擇主表
    • 一般選擇帶“排序字段”的表作為主表,最終的目的是“分頁+排序”只存在於主表
    • 主輔表都可以有“動態查詢”
  2. 先操作輔表
    • 對輔表進行動態查詢等操作,獲取邏輯外鍵的Set集合;
    • 把輔表查詢得到的邏輯外鍵的Set集合,返回給主表;
  3. 再操作主表
    • 把輔表返回的邏輯外鍵的Set集合當做一個查詢條件
      Predicate predicate = root.get("ip").as(String.class).in(ipCollect);
  4. 完成分頁和排序操作
    • 還是利用Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable)完成“分頁+排序”操作
  5. 填充輔表字段
    • 對分頁結果進行Stream操作,補上輔表的字段信息
    • 最終的pagesize數量不會很大,補充字段的操作性能消耗不會很大;
    • Page<T>的返回結果可以通過在entity中補充@Transient字段,后續進行填充

三、相關問題:

  1. 最后生成的SQL是什么樣子的?
    • 是SQL子查詢
  2. 多個表都有排序字段的情況下,怎么確定主表?
    • 根據傳入的排序字段名,決定哪張為主表,這種情況發生時,大概率是表結構的設計有問題
  3. 這么做的意義是什么?
    • “面向DB編程” VS “面向對象編程”
    • 業務邏輯盡可能放在代碼里實現,而不是SQL中
    • 在互聯網開發背景下,更傾向於把DB當中帶事務支持的容器,把DB的性能壓力解耦到應用層
    • 少手寫JPQL/SQL,少用JOIN,可以在數據庫字段頻繁變更,需求頻繁變化的情況下,提高開發效率
  4. 這個方案有什么不好的地方嗎?
    • JPA在沒有物理外鍵的情況下,無法構建級聯關系,這個方法確實可用,但不優雅
  5. 待補充


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM