時隔8個月,分頁外掛這次帶來了一次大的更新。
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
引數配置攔截器,執行時存在下面三種情況:
不管當前執行的 SQL 是否會分頁,都會執行 Type.ORIGINAL
型別的攔截器方法,配置後一定會執行。
呼叫分頁方法時,攔截器會繼續執行 Type.COUNT_SQL
型別的攔截器方法,這個方法只有執行分頁並且指定要進行 count 查詢時才會執行。
呼叫分頁方法時,如果 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; } });
在 pom.xml 中新增如下依賴:
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency>
PageHelperAutoConfiguration
增加 @Lazy(false)
註解,當配置延遲載入時,避免分頁外掛出錯
[admin
]