歡迎您光臨本站 註冊首頁

Mybatis 分頁外掛 PageHelper 5.2.0 釋出

←手機掃碼閱讀     admin @ 2020-07-27 , reply:0

時隔8個月,分頁外掛這次帶來了一次大的更新。

5.2.0 - 2020-07-26

  • jsqlparser升級到3.2版本,sql解析更好,對sqlserver支援更好。

  • 修改 sqlserver 方式中的替換正則,現在允許 with( nolock ) 括號中存在空格。

  • 解決 reasonable 和 pageSizeZero,以及 offset 用法中的bug,現在的含義和結果更一致。

  • 分頁 SQL 拼接過程中增加換行符,避免原始 SQL 中存在註釋導致分頁部分無效。

  • Oracle 和 Db2 中的行號 ROW_ID 別名改為 PAGEHELPER_ROW_ID,避免和常用名稱衝突。

  • 解決單個引數ProviderSql使用其他攔截器時的特殊問題(支援 mybatis 3.4.0+)by 羅震宇

  • 支援自動識別 clickhouse,使用 MySQL 方式進行分頁。

  • 將 startRow, endRow 型別從 int 改為 long。

  • Page 增加 public <T> PageInfo<T> toPageInfo(Function<E, T> function) 方法,用於轉換查詢結果中的資料。

  • 參考 pr#476 提供 ·Oracle9iDialect`,這也是曾經用過的一種分頁方式,可以自己測試選擇合適的分頁方式。

    目前提供的兩種 Oracle 分頁如下:

    
 -- OracleDialect 外層控制範圍
 WHERE ROW_ID <= ? AND ROW_ID > ?
 -- Oracle9iDialect 內外分別控制範圍
 TMP_PAGE WHERE ROWNUM <= ? ) WHERE ROW_ID > ?
  • 增加分頁外掛的 BoundSqlInterceptor 攔截器,可以在3個階段對 SQL 進行處理或者簡單讀取, 增加引數 boundSqlInterceptors,可以配置多個實現 BoundSqlInterceptor 介面的實現類名, 使用英文逗號隔開。PageHelper呼叫時,也可以通過類似 PageHelper.startPage(x,x).boundSqlInterceptor(BoundSqlInterceptor boundSqlInterceptor)針對本次分頁進行設定。

本次更新最大的變化是增加了 BoundSqlInterceptor,通過該介面可以在執行時攔截分頁處理的 SQL(BoundSQL物件):


 /**
  * BoundSql 處理器
  */
 public interface BoundSqlInterceptor {
     /**
      * boundsql 處理
      *
      * @param type     型別
      * @param boundSql 當前型別的 boundSql
      * @param cacheKey 快取 key
      * @param chain    處理器鏈,通過 chain.doBoundSql 方法繼續執行後續方法,也可以直接返回 boundSql 終止後續方法的執行
      * @return 允許修改 boundSql 並返回修改後的
      */
     BoundSql boundSql(Type type, BoundSql boundSql, CacheKey cacheKey, Chain chain);
 
     enum Type {
         /**
          * 原始SQL,分頁外掛執行前,先執行這個型別
          */
         ORIGINAL,
         /**
          * count SQL,第二個執行這裡
          */
         COUNT_SQL,
         /**
          * 分頁 SQL,最後執行這裡
          */
         PAGE_SQL
     }
 
     /**
      * 處理器鏈,可以控制是否繼續執行
      */
     interface Chain {
         Chain DO_NOTHING = new Chain() {
             @Override
             public BoundSql doBoundSql(Type type, BoundSql boundSql, CacheKey cacheKey) {
                 return boundSql;
             }
         };
 
         BoundSql doBoundSql(Type type, BoundSql boundSql, CacheKey cacheKey);
     }
 }

介面中包含了 boundSql 介面方法,還有 Type 列舉,和 Chain 介面的定義,自己實現的時候不需要考慮 Chain。

通過 boundSqlInterceptors 引數配置攔截器,執行時存在下面三種情況:

  1. 不管當前執行的 SQL 是否會分頁,都會執行 Type.ORIGINAL 型別的攔截器方法,配置後一定會執行。

  2. 呼叫分頁方法時,攔截器會繼續執行 Type.COUNT_SQL 型別的攔截器方法,這個方法只有執行分頁並且指定要進行 count 查詢時才會執行。

  3. 呼叫分頁方法時,如果 count > 0,就會執行 Type.PAGE_SQL 型別的攔截器方法,這個方法只有執行分頁時才會執行。

通過 PageHelper.startPage(1, Integer.MAX_VALUE, false).boundSqlInterceptor(BoundSqlInterceptor boundSqlInterceptor) 這種指定的引數時,也能起到不進行分頁和count查詢,但是可以執行 Type.ORIGINAL 型別的攔截器方法。

當前攔截器在整個分頁執行過程中,會執行3次,對應 Type 列舉的 3 個型別,執行順序也一致。

如果想獲取分頁 SQL 執行前的,只需要關注 Type.ORIGINAL,另外兩種就是 count 執行前和分頁執行前(count=0時分頁方法不執行,這裡也不會執行)。

以測試程式碼為例:


 public class TestBoundSqlInterceptor implements BoundSqlInterceptor {
     public static final String COMMENT = "\n /* TestBoundSqlInterceptor */\n";
 
     @Override
     public BoundSql boundSql(Type type, BoundSql boundSql, CacheKey cacheKey, Chain chain) {
         if (type == Type.ORIGINAL) {
             String sql = boundSql.getSql();
             MetaObject metaObject = MetaObjectUtil.forObject(boundSql);
             metaObject.setValue("sql", sql + COMMENT);
         }
         return chain.doBoundSql(type, boundSql, cacheKey);
     }
 
 }

上面這段程式碼在 sql 執行前先修改原始 SQL,只是在最後增加了一段註釋,不影響 SQL 執行,通過下面的方式配置:


 <plugin interceptor="com.github.pagehelper.PageInterceptor">
     <!-- 支援通過Mapper介面引數來傳遞分頁引數 -->
     <property name="helperDialect" value="mysql"/>
     <property name="boundSqlInterceptors"
               value="com.github.pagehelper.test.basic.provider.TestBoundSqlInterceptor,com.github.pagehelper.test.basic.provider.TestBoundSqlInterceptor"/>
 </plugin>

這裡為了說明該引數值可以是多個,因此重複配置了一次,也就是上面的攔截器會執行兩次。

這樣配置後,上面的 SQL 在分頁執行的時候就會修改 SQL。

除了這種配置方式外,還支援 PageHelper.startPage 時臨時指定,這種方式會把攔截器放到鏈頭先執行,因此可以控制後續的是否執行,也可以在後續所有執行外,做最後處理再返回。

示例:


 PageHelper.startPage(1, 10).boundSqlInterceptor(new BoundSqlInterceptor() {
     @Override
     public BoundSql boundSql(Type type, BoundSql boundSql, CacheKey cacheKey, Chain chain) {
         System.out.println("before: " + boundSql.getSql());
         BoundSql doBoundSql = chain.doBoundSql(type, boundSql, cacheKey);
         System.out.println("after: " + doBoundSql.getSql());
         if (type == Type.ORIGINAL) {
             Assert.assertTrue(doBoundSql.getSql().contains(TestBoundSqlInterceptor.COMMENT));
         }
         return doBoundSql;
     }
 });
 

pagehelper-spring-boot-starter

在 pom.xml 中新增如下依賴:


 <dependency>
     <groupId>com.github.pagehelper</groupId>
     <artifactId>pagehelper-spring-boot-starter</artifactId>
     <version>1.3.0</version>
 </dependency>

v1.3.0 - 2020-07-26

  • 升級 PageHelper 到 5.2.0,包含大量改動
  • 升級 MyBatis 到 3.5.5
  • 升級 MyBatis Starter 到 2.1.3
  • 升級 springboot 到 2.3.1.RELEASE
  • PageHelperAutoConfiguration 增加 @Lazy(false) 註解,當配置延遲載入時,避免分頁外掛出錯
  • 新增分頁外掛時判斷是否已經配置過同一個例項(不同的配置是不同的例項)
 

[admin ]

來源:OsChina
連結:https://www.oschina.net/news/117484/pagehelper-5-2-0-released
Mybatis 分頁外掛 PageHelper 5.2.0 釋出已經有263次圍觀

http://coctec.com/news/all/show-post-245401.html