背景
上周写了一篇分享文,有大佬回复介绍了一个开源的PageHelper工具,就去了解学习了一下
简单介绍
首先甩出一个GitHub链接Mybatis-PageHelper
简单地看了一下源码,其实实际的原理是一样的,自定义了一个分页的拦截器,不过PageHelper拦截的方法是Executor.class
中的query
方法。
观察源码会发现,与我之前那篇文章中的实现相比,不同的是,PageHelper在完成了select count(1)
即计数的功能之后,对于原sql的分页查询,全部在Interceptor中完成了,而不是在select count(1)
之后,修改原sql,继续由invocation.proceed()来执行:
1 | // PageInterceptor第113行,查询数量 |
这样做的好处就是可以在sql查询完成之后,继续对返回的List进行处理,例如PageHelper在afterPage方法中做的就是讲返回的List对象中的数据取出,放到Page对象中(Page是继承自List的类,其中增加了pageNum、pageSize、total之类的属性)
示例
首先还是要给sqlSessionFactoryBean注册plugin,不过这一次不能直接在SQLSessionFactoryBean中写入了,因为PageInterceptor需要通过setProperties(Properties properties)方法初始化dialect,如果直接在application-database中通过
正确的方式是,通过mybatis的config.xml注册plugin:
1 | // 错误方式 |
接下来,只要在需要使用分页的地方先写一次分页参数:
PageHelper.startPage(1, 5);
然后继续执行dao方法,就可以完成分页:
List<String> testList = sampleDao.listTitle(4281);
此处虽然我是使用List来接受的结果,实际上这是一个Page对象,若想要获得total、pageNum、pageSize等信息,可以直接用Page来接受结果,或者用PageInfo对象来转换结果:
Page<String> testList = sampleDao.listTitle(4281);
PageInfo<String> pageInfo = new PageInfo<>(stringList);
结论
总体而言,PageHelper确实比自己造一个轮子要方便实用的多。
再写两个遇到的坑…
- 引入PageHelper的时候要注意版本,貌似5.0.0之前的版本,拦截器的类是PageHelper,进入5.0.0之后变为了PageInterceptor
- 5.0.0之前,注册plugin时要指定dialect,即加入一个参数;现在是不要指定dialect,会默认指定一个通用的,如果自己写很容易写错,例如我测试时写了一个MySqlDialect,结果这个东西并不是这么用的