概述
如果你也在用 MyBatis,建议尝试该分页插件,这一定是最方便使用的分页插件。分页插件支持任何复杂的单表、多表分页。我们在项目中使用sql的手动分页太常见了,如果前台需要分页信息的话,一般我们是需要2条slq语句,一条是查询总页数count,一条是查询分页数据,有了PageHelper后一切方便了,并且添加的代码很少,来一起学习吧。
官方参考文档 :https://pagehelper.github.io
官方Github地址:https://github.com/pagehelper/Mybatis-PageHelper
1.引入分页插件
引入分页插件有下面2种方式,推荐使用 Maven 方式。
1). 引入 Jar 包
你可以从下面的地址中下载最新版本的 jar 包
-
https://oss.sonatype.org/content/repositories/releases/com/github/pagehelper/pagehelper/
-
http://repo1.maven.org/maven2/com/github/pagehelper/pagehelper/
由于使用了sql 解析工具,你还需要下载 jsqlparser.jar:
2). 使用 Maven(推荐)
在 pom.xml 中添加如下依赖:(最新5.1.10)
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
2. 配置拦截器插件
常见的参数配置只关注helperDialect=mysql(方言),reasonable=true(分页合理化)就可以了,其他可使用默认。下面的配置2.1和2.2选择其中一个配置就可以,推荐2.1中在mybatis的配置文件中配置。
2.1 在 MyBatis 配置 xml 中配置拦截器插件
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql" />
<!-- 该参数默认为false -->
<!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
<!-- 和startPage中的pageNum效果一样 -->
<property name="offsetAsPageNum" value="true" />
<!-- 该参数默认为false -->
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true" />
<!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
<!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型) -->
<property name="pageSizeZero" value="true" />
<!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
<!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
<!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
<property name="reasonable" value="false" />
<!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
<!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
<!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值 -->
<!-- 不理解该含义的前提下,不要随便复制该配置 -->
<property name="params" value="pageNum=start;pageSize=limit;" />
<!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
<property name="returnPageInfo" value="check" />
</plugin>
</plugins>
2.2 在 Spring 配置文件中配置拦截器插件
使用 spring 的属性配置方式,可以使用 plugins
属性像下面这样配置:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注意其他配置 -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="dialect" value="mysql" />
<!-- 该参数默认为false -->
<!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
<!-- 和startPage中的pageNum效果一样 -->
<property name="offsetAsPageNum" value="true" />
<!-- 该参数默认为false -->
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true" />
<!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
<!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型) -->
<property name="pageSizeZero" value="true" />
<!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
<!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
<!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
<property name="reasonable" value="false" />
<!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
<!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
<!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值 -->
<!-- 不理解该含义的前提下,不要随便复制该配置 -->
<property name="params" value="pageNum=start;pageSize=limit;" />
<!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
<property name="returnPageInfo" value="check" />
</bean>
</array>
</property>
</bean>
3. 如何在代码中使用
官方推荐用法:PageHelper.startPage
静态方法调用
其实用法很简单就是在正常查询方法上添加一句话:
PageHelper.startPage(1, 10);// 参数:page, size
List<Country> list = countryMapper.selectIf(1);// 正常查询的方法
如果需要更详细的分页信息的话:如总页数,当前页,是否首页,是否尾页,等等...只需要用PageInfo将查询列表包装起来,前台可以使用pageInfo来处理前端的分页插件 。
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectAll();
//用PageInfo对结果进行包装
PageInfo pageInfo = new PageInfo(list);
以下是PageInfo的属性,可参考:
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//当前页的数量
private int size;
//由于startRow和endRow不常用,这里说个具体的用法
//可以在页面中"显示startRow到endRow 共size条数据"
//当前页面第一个元素在数据库中的行号
private int startRow;
//当前页面最后一个元素在数据库中的行号
private int endRow;
//总记录数
private long total;
//总页数
private int pages;
//结果集
private List < T > list;
//前一页
private int prePage;
//下一页
private int nextPage;
//是否为第一页
private boolean isFirstPage = false;
//是否为最后一页
private boolean isLastPage = false;
//是否有前一页
private boolean hasPreviousPage = false;
//是否有下一页
private boolean hasNextPage = false;
//导航页码数
private int navigatePages;
//所有导航页号
private int[] navigatepageNums;
//导航条上的第一页
private int navigateFirstPage;
//导航条上的最后一页
private int navigateLastPage;
重要提示
PageHelper.startPage
方法重要提示
只有紧跟在PageHelper.startPage
方法后的第一个Mybatis的查询(Select)方法会被分页。
请不要配置多个分页插件
请不要在系统中配置多个分页插件(使用Spring时,mybatis-config.xml
和Spring<bean>
配置方式,请选择其中一种,不要同时配置多个分页插件)!
分页插件不支持带有for update
语句的分页
对于带有for update
的sql,会抛出运行时异常,对于这样的sql建议手动分页,毕竟这样的sql需要重视。
分页插件不支持嵌套结果映射
由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。
4. MyBatis 和 Spring 集成示例
集成可参考:https://github.com/abel533/Mybatis-Spring
(完)