1. 程式人生 > >PageHelper-----Mybatis分頁外掛

PageHelper-----Mybatis分頁外掛

PageHelper的使用 1、pageHelper的maven依賴及外掛配置:com.github.pagehelper

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>4.1.6</version>
</dependency>

PageHelper除了本身的jar包外,他還依賴了一個叫jsqlparser的jar包,使用時,我們不需要單獨指定jsqlparse的maven依賴,maven的間接依賴會幫我們引入 2、註冊mybatis plugin 跟其它Mybatis Plugin一樣,我們需要在Mybatis的配置檔案中註冊需要使用的Plugin,PageHelper中對應的Plugin實現類就是com.github.pagehelper.PageHelper自身。順便說一句,Mybatis的Plugin我們說是Plugin,實際上對應的卻是org.apache.ibatis.plugin.Interceptor介面,因為Interceptor的核心是其中的plugin(Object target)方法,而對於plugin(Object target)方法的實現,我們在需要對對應的物件進行攔截時會通過org.apache.ibatis.plugin.Plugin的靜態方法wrap(Object target, Interceptor interceptor)返回一個代理物件,而方法入參就是當前的Interceptor實現類。

<!-- com.github.pagehelper為PageHelper類所在包名,在 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
    <!--標識的是哪一種資料庫,設計上必須-->
    <property name="dialect" value="mysql" />
    <!-- 該引數預設為false -->
    <!-- 設定為true時,會將RowBounds第一個引數offset當成pageNum頁碼使用 -->
<!-- 和startPage中的pageNum效果一樣 --> <property name="offsetAsPageNum" value="false" /> <!-- 該引數預設為false --> <!-- 設定為true時,使用RowBounds分頁會進行count查詢 --> <property name="rowBoundsWithCount" value="true" /> <!-- 設定為true時,如果pageSize=0或者RowBounds.limit = 0就會查詢出全部的結果 -->
<!-- (相當於沒有執行分頁查詢,但是返回結果仍然是Page型別) <property name="pageSizeZero" value="true"/> --> <!-- 3.3.0版本可用 - 分頁引數合理化,預設false禁用 --> <!-- 啟用合理化時,如果pageNum<1會查詢第一頁,如果pageNum>pages會查詢最後一頁 --> <!-- 禁用合理化時,如果pageNum<1或pageNum>pages會返回空資料 --> <property name="reasonable" value="true" /> <!-- 3.5.0版本可用 - 為了支援startPage(Object params)方法 --> <!-- 增加了一個`params`引數來配置引數對映,用於從Map或ServletRequest中取值 --> <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置對映的用預設值 --> <!-- 不理解該含義的前提下,不要隨便複製該配置 <property name="params" value="pageNum=start;pageSize=limit;"/> --> <!-- 以下的3個智慧引數,不到萬不得已,我們不應該在系統中使用 <!--是否自動檢測dialect--> <property name="autoDialect" value="true" /> <!--多資料來源時,是否自動檢測dialect。--> <property name="autoRuntimeDialect" value="true" /> <!--檢測完dialect後,是否關閉Connection連線--> <property name="closeConn" value="true" /> --> </plugin>

3、使用PageHelper PageHelper攔截的是org.apache.ibatis.executor.Executor的query方法,其傳參的核心原理是通過ThreadLocal進行的。當我們需要對某個查詢進行分頁查詢時,我們可以在呼叫Mapper進行查詢前呼叫一次PageHelper.startPage(..),這樣PageHelper會把分頁資訊存入一個ThreadLocal變數中。在攔截到Executor的query方法執行時會從對應的ThreadLocal中獲取分頁資訊,獲取到了,則進行分頁處理,處理完了後又會把ThreadLocal中的分頁資訊清理掉,以便不影響下一次的查詢操作。所以當我們使用了PageHelper.startPage(..)後,每次將對最近一次的查詢進行分頁查詢,如果下一次查詢還需要進行分頁查詢,需要重新進行一次PageHelper.startPage(..)。這樣就做到了在引入了分頁後可以對原來的查詢程式碼沒有任何的侵入性。此外,在進行分頁查詢時,我們的返回結果一般是一個java.util.List,PageHelper分頁查詢後的結果會變成com.github.pagehelper.Page型別,其繼承了java.util.ArrayList,所以不會對我們的方法宣告造成影響。com.github.pagehelper.Page中包含有返回結果的分頁資訊,包括總記錄數,總的分頁數等資訊,所以一般我們需要把返回結果強轉為com.github.pagehelper.Page型別。以下是一個簡單的使用PageHelper進行分頁查詢的示例程式碼。

4、程式碼實現

@RequestMapping("/testPageHelper")
    @ResponseBody
    public Wrapper<Object> testPageHelper(Integer pageNum,Integer pageSize) {
        PageInfo<Dict> pageinfo =null;
        try {
            PageHelper.startPage(pageNum, pageSize);
            List<Dict> dictList = dictService.firstplatformlistAll();
            pageinfo = new PageInfo<Dict>(dictList);

        } catch (Exception e) {
            return WrapMapper.error();
        }
        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE,pageinfo);
    }

注(自己理解):PageHelper.startPage(pageNum, pageSize)返回型別為Page型別,該Page型別繼承了ArrayList,並將Page存放到ThreadLocal中。當執行到下一行程式碼查詢dictList時,會在threadlocal中查詢是否有Page,如果有會把查詢出的資料封裝到Page中並返回其父類List,在PageInfo有二個建構函式PageInfo(List list)、PageInfo(List list, int navigatePages),navigatePages是頁碼顯示數量,預設是8,在建立PageInfo時,可以選擇任意一種構造方法,如果使用第一個構造方法,PageInfo中最終的實現也是由第二個構造方法,在第二個構造方法中,會將dictList轉換為Page型別,然後將Page中的資料存放到PageInfo中,並返回。其中PageInfo類比Page類中多一些業務處理,Page中只負責與資料庫互動,儲存資料,PageInfo做一些邏輯處理(比如導航頁的計算顯示,以及一些合理化的處理)