PageHelper plug-in principle

 

Introduction

PageHelper is a good mybatis pagination plug-ins. After a simple configuration, only a few lines of code can be achieved paging query.

Database data as follows:

 @RequestMapping("/findAllUser")

public ResponseResult<PageBean> findAllUser2(PageModel pageModel) {
  PageHelper.startPage(pageModel.getPageNum(), pageModel.getPageSize());
  PageHelper.orderBy("id desc");
  List<MyUser> myUsers = myUserServices.selectUser();
  PageBean<MyUser> pageBean = new PageBean<>(myUsers);
  return new ResponseResult<>(200, "success", pageBean);
}

 

 

The code looks rather strange, just passed in the size of the number of pages per page has currently required can be achieved query pagination of mybatis; in addition can also be achieved ascending and descending order.

  1. How does it do it? Are you using dynamic proxy?
  2. It is to implement paging through sql?
  3. PageHelper.startPage () is not used ThreadLocal? When released inside the ThreadLocal value? It will result in ThreadLocal memory leaks?

With these questions I had source code analysis, this article does not describe how to configure implement paging function, the code can be downloaded from here:  https://github.com/pmh905001/freedom-20200203springboot

Mainly to explore the realization of the principle of PageHelper can learn some ideas from this article to the source code analysis.

 

obtain

Analysis of how to start realization of the principle PageHelper it?

The current code is the controller ---> service ---> Mapper simply a few lines of code can not see the inside track to achieve, to exclude this method.

Since its code which sets pageSize, PageHelper.startPage (pageModel.getPageNum (), pageModel.getPageSize ()); then it must have a place to use it, we follow this method can track here

  

 

 PageHelper Principle Analysis

 See here is actually answer my third question: PageHelper.startPage () is not used ThreadLocal? Yes, it is the use of ThreadLocal.

Then we are in this field we are in the PageSize to do a trace breakpoint. We can get the call stack as follows:

 

 We can find a proxy class named PageInterceptor of mybatis SQL being executed were intercepted, the total number of first query, and then performing paging query. 

And we can see from the following statement this dynamic proxy class is intercepted Executor class inside the query method.

 

Analysis here has actually answered my first question.

  1. How does it do it? Are you using dynamic proxy?

He was intercepted by a dynamic proxy Executor.query () method. And he should bring their own java dynamic proxy implementation.

 

By analyzing PageInterceptor, we can also answer Question 2:

  2. it is to implement paging through sql?

It is to implement paging through sql, not described in detail here.

 

 other

Another problem is that we see PageHelper is to set the paging information through ThreadLocal, then what place the paging information to release it? Or it may cause a memory leak.

PageHelper里面有一个clearPage()方法,反向查看调用点即可以知道程序在哪儿释放分页信息。

 

 

从上面的代码可以看出,拦截器执行完毕之后最终会释放分页信息。并且放在finally块中,可以保证不会出现ThreadLocal内存泄漏。

 

还有一个问题,Mybatis是否支持Executor多个拦截器,比如:分页拦截器和排序拦截器,答案是肯定的。Mybatis使用提供了一种插件的机制,读者可以参考一下InterceptorChain.pluginAll()方法。

 

 这里代码有点绕,我之前看到这里感觉很别扭,这应该只返回一个动态代理类,怎么会支持多层拦截呢? 实际上这里代码写的很精炼,每一次循环相当于被代理上面套了一层,第二次循环就会再在动态代理类基础上再封装一层.

 

Guess you like

Origin www.cnblogs.com/pmh905001/p/12286008.html