mybatis(7) - 分頁

在處理sql分頁的場景,可與選擇在內存中對所有數據進行sublist,或在寫sql時指定limit。那如何利用mybatis的特性在處理分頁呢?java

 

物理分頁-sql語句指定limit

適用於數據量大的狀況下。sql

limit的效能越到後面越慢,以LIMIT N,M爲基礎:LIMIT首先要找查N+M行,而後從N行處,取M行;因此在大數量作分頁查詢時,越日後分頁,LIMIT語句的偏移量就越大,速度也明顯變慢 。對於LIMIT這類的優化:數組

  1. 第一個目標就是讓N變的儘量的小或是不用。
  2. 儘量的明確好查詢的限制條件,精確縮小數據範圍。
  1. 第一種: 在真正執行sql以前,經過對StatementHandler的攔截,對原有的sql (statementHandler.getBoundSql().getSql)拼接limit語句。
    自定義插件Interceptor 方式: @Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})
  2. 第二種: 直接在sql.xml中的sql語句中顯示申明limit語句。

RowBounds對於limit的處理

數據量小時可用。mybatis

用起來極爲方便,先給接口增長一個RowBounds參數。app

public List<RoleBean> queryRolesByPage(String roleName, int start, int limit) {
        return roleDao.queryRolesByPage(roleName, new RowBounds(start, limit));
    }

MyBatis在初始化每一個Mapper的代理對象MapperProxy時,會經過MethodSignature來標記每個mapper方法中的RowBounds在方法argument數組的位置。優化

MapperMethod.execute 選擇分支方法executeWithResultHandler 裏會獲取到RowBounds傳遞到構建的StatementHandler 對象中(內部成員變量ResultSetHandler 也綁定該RowBounds)。 由ResultSetHandler.handleResultSets 最終調用handleRowValues方法解析數據時根據RowBounds參數進行分頁。spa

RowBounds中有兩個數字,offset和limit。在處理分頁時,在DefaultResultSetHandler中,只是簡單的把offset以前的數據都skip掉,超過limit以後的數據不取出。 就是先把數據所有查詢到ResultSet,而後從ResultSet中取出offset和limit之間的數據。插件

相關文章
相關標籤/搜索