[Mybatis][PageHelper]對PageHelper的一點理解。

首先, PageHelper的使用, 很簡單,導入依賴,寫幾行簡單的代碼。

<!--MyBatis分頁插件starter-->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>${pagehelper-starter.version}</version>
</dependency>

    //獲取第1頁,10條內容,默認查詢總數count
    PageHelper.startPage(1, 10);
    //緊跟着的第一個select方法會被分頁
    List<Country> list = userDAO.find();

接下來我們瞭解下PageHelper如何實現分佈的。

    首先我們考慮兩個問題。

   1) 從上面的代碼看, userDAO.find完成沒有使用到PageHelper相關的參數,那它如何實現分頁的? 
答案就是通過PageHelperAutoConfiguration類,向mybatis中添加了pageHelper的攔截器, 如下:

//com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration    
@PostConstruct
    public void addPageInterceptor() {
        PageInterceptor interceptor = new PageInterceptor();
        Properties properties = new Properties();
        //先把一般方式配置的屬性放進去
        properties.putAll(pageHelperProperties());
        //在把特殊配置放進去,由於close-conn 利用上面方式時,屬性名就是 close-conn 而不是 closeConn,所以需要額外的一步
        properties.putAll(this.properties.getProperties());
        interceptor.setProperties(properties);
        for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
            sqlSessionFactory.getConfiguration().addInterceptor(interceptor);
        }
    }

 

2) PageHelper.startPage(1, 10)是靜態函數,如何保證各個線程之間不互相影響?

用synchronize,lock, 這些肯定不行。一定是用ThreadLocal.

考慮到Spring對http的請求的處理機制, 每個請求對應一個處理線程,大家就很容易理解爲什麼用ThreaLocal.

下面看代碼:

public abstract class PageMethod {
    protected static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal<Page>();
    protected static boolean DEFAULT_COUNT = true;

    /**
     * 設置 Page 參數
     *
     * @param page
     */
    protected static void setLocalPage(Page page) {
        LOCAL_PAGE.set(page);
    }
...
}

       

 

結論:

1)PageHelper通過PageHelperAutoConfiguration類向Mybatis註冊了攔截器,在查詢時候,將分頁信息傳遞給Mybatis框架,你通過mybatis查詢的時候能夠使用分頁查詢。

2) PageHelper通過ThreadLocal保證每個查詢使用的分頁信息就是通過PageHelperg靜態函數startPage傳遞的參數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章