[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传递的参数。

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