【快速实现分页】MyBatis-Plus 整合 PageHelper
MyBatis-Plus自带分页PaginationInterceptor
对象,但想要用MyBatis-Plus自带的分页功能的话需要在mapper对象中传入一个Page对象才可以实现分页,这样耦合度是不是太高了一点,从web到service到mapper,这个Page对象一直都在传入,这样的使用让人感觉有点麻烦,但是Mapper Plus不得不说真的是很好用的。
PageHelper是国内非常优秀的一款开源的mybatis分页插件,它支持基本主流与常用的数据库,例如mysql、oracle、mariaDB、DB2、SQLite、Hsqldb等。只要一行代码就能实现分页
现在将这两个好用的框架整合在一起
1. pom引入
<!--pagehelper分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
<!-- Mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
我用的是Spring Boot框架,在pom中直接引入MyBatis Plus
和PageHelpe
r就可以了;
2. 配置文件
MyBatis-Plus的
配置我就不贴出来了,主要贴出PageHelper
的配置
application.properties
#分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置helperDialect 属性来指定分页插件使用哪种方言。
pagehelper.helper-dialect=mysql
#分页合理化参数,默认值为 false 。当该参数设置为 true 时, pageNum<=0 时会查询第一页, pageNum>pages (超过总数时),会查询最后一页。
pagehelper.reasonable=true
#支持通过Mapper接口参数传递page参数,默认值为falset
pagehelper.support-methods-arguments=true
#默认值为 false ,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit =0 就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是 Page 类型)。
pagehelper.pageSizeZero=true
#为了支持 startPage(Object params) 方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值
pagehelper.params=count=countSql
application.yml
pagehelper:
auto-dialect: mysql
reasonable: true
support-methods-arguments: true
page-size-zero: true
params: count=countSql
3. 使用
使用起来很方便,我用一个controller的list接口作为示范
@RequestMapping("/page/{pn}")
public ResultData<PageInfo> cityPage(@PathVariable Integer pn){
try {
//1.引入分页插件,pageNum是第几页,pageSize是每页显示多少条,默认查询总数count
Page<City> page = PageHelper.startPage(pn,3);
//2.紧跟的查询就是一个分页查询-必须紧跟.后面的其他查询不会被分页
List<City> cityList = cityService.list();
//3.使用PageInfo包装查询后的结果,3是连续显示的条数
PageInfo pageInfo = new PageInfo(cityList, 3);
}finally {
//清理 ThreadLocal 存储的分页参数,保证线程安全
PageHelper.clearPage();
}
return new ResultData<PageInfo>().setData(pageInfo);
}
PageHelper.startPage(pageNum, pageSize);
这一行代码就实现了分页,
通过PageInfo
对象将数据包装返回即可。
PageHelper中文文档
重要提示:
- 只有紧跟在PageHelper.startPage()方法后的第一个Mybatis的查询(Select)方法会被分页。
- 请不要在系统中配置多个分页插件(使用Spring时,mybatis-config.xml和Spring配置方式,请选择其中一种,不要同时配置多个分页插件)!
- 对于带有for update的sql,会抛出运行时异常,对于这样的sql建议手动分页,毕竟这样的sql需要重视。
- 由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。
4. 效果
未分页
PageInfo类所有属性
pageNum:当前为第几页
pageSize:每页的数据行数
startRow:当前页数据从第几条开始
endRow:当前页数据从第几条结束
pages:总页数
prePage:上一页页数
nextPage:下一页页数
hasPreviousPage:是否有上一页
hasNextPage:是否有下一页
navigatepageNums:所有页码的数组
我们可以根据这几个属性控制页面切换的操作,比如hasPreviousPage
为false表示没有上一页,
当前为首页,我们可以控制页面不显示或者不能使用首页和上一页功能。非常的简单。
下面是我做的一个小项目示例图:
有人说PageHelper 是不安全的分页?
实际上PageHelper 方法使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的。
只要你可以保证在 PageHelper 方法调用后紧跟 MyBatis 查询方法,这就是安全的。因为 PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。
参考博客