1. 程式人生 > >Mybatis分頁外掛——PageHelper使用與原理介紹

Mybatis分頁外掛——PageHelper使用與原理介紹

推薦一款Mybatis分頁外掛

以前也寫過一篇博文介紹Mybatis的外掛,以及如何通過Mybatis的外掛功能實現一個自定義的分頁外掛,但是那個外掛的侵入性是比較大的。前段時間遇到了一款開源的Mybatis分頁外掛,叫PageHelper,github地址是https://github.com/pagehelper/Mybatis-PageHelper,其原理是通過ThreadLocal來存放分頁資訊,從而可以做到在Service層實現無侵入性的Mybatis分頁實現。筆者感覺還不錯,所以特意發博文記錄一下,並推薦給大家。

簡單示例

以下是使用PageHelper進行分頁的一個簡單的示例,更多詳細的內容,請大家引數上面提供的github地址

新增依賴

筆者使用的是Maven,新增依賴如下。

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>4.1.6</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

註冊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實現類。

    <plugins>  
       <plugin interceptor="com.github.pagehelper.PageHelper"/>  
    </plugins>
  • 1
  • 2
  • 3

使用PageHelper

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

public class PageHelperTest {

    private static SqlSessionFactory sqlSessionFactory;
    private SqlSession session;

    @BeforeClass
    public static void beforeClass() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis-config-single.xml");
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    }

    @Before
    public void before() {
        this.session = sqlSessionFactory.openSession();
    }

    @After
    public void after() {
        this.session.close();
    }

    @Test
    public void test() {
        int pageNum = 2;//頁碼,從1開始
        int pageSize = 10;//每頁記錄數
        PageHelper.startPage(pageNum, pageSize);//指定開始分頁
        UserMapper userMapper = this.session.getMapper(UserMapper.class);
        List<User> all = userMapper.findAll();
        Page<User> page = (Page<User>) all;
        System.out.println(page.getPages());
        System.out.println(page);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

以上是通過PageHelper.startPage(..)傳遞分頁資訊的示例,其實PageHelper還支援Mapper引數傳遞分頁資訊等其它用法。關於PageHelper的更多用法和配置資訊等請參考該專案的GitHub官方文件

(本文由Elim寫於2017年5月31日)