1.1. PageHelper的介绍
PageHelper是国内非常优秀的一款开源的mybatis分页插件,它支持基本主流与常用的数据库,例如mysql、oracle、mariaDB、DB2、SQLite、Hsqldb等。
网址:https://pagehelper.github.io/
本项目在 github 的项目地址:https://github.com/pagehelper/Mybatis-PageHelper
本项目在 gitosc 的项目地址:http://git.oschina.net/free/Mybatis_PageHelper
分页插件学习文档:https://pagehelper.github.io/docs/howtouse/
1.2. PageHelper集成到项目中
引入分页插件有下面2种方式,推荐使用 Maven 方式。
1.2.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:http://repo1.maven.org/maven2/com/github/jsqlparser/jsqlparser/0.9.5/
1.2.2. Maven方式
今天我们使用5.1.8的版本,分别在父工程和dao工程中导入以上包,父工程做版本的管理,子工程直接使用。
1.2.3. 配置PageHelper
特别注意,新版拦截器是 com.github.pagehelper.PageInterceptor。 com.github.pagehelper.PageHelper 现在是一个特殊的 dialect 实现类,是分页插件的默认实现类,提供了和以前相同的用法。
1.2.3.1. 在 MyBatis 配置 xml 中配置拦截器插件
1.2.3.2. 在 Spring 配置文件中配置拦截器插件
使用 spring 的属性配置方式,可以使用 plugins 属性像下面这样配置:
在ssm_dao的spring-mybatis.xml中添加配置:
1.2.3.3. 分页插件参数介绍
1:helperDialect:
分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:
oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby
特别注意:使用 SqlServer2012 数据库时,需要手动指定为 sqlserver2012,否则会使用 SqlServer2005 的方式进行分页。
你也可以实现 AbstractHelperDialect,然后配置该属性为实现类的全限定名称即可使用自定义的实现方法。
2:offsetAsPageNum:
默认值为 false,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为 true 时,会将 RowBounds 中的 offset 参数当成 pageNum 使用,可以用页码和页面大小两个参数进行分页。
3:rowBoundsWithCount:
默认值为false,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为true时,使用 RowBounds 分页会进行 count 查询。
4:pageSizeZero:
默认值为 false,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是 Page 类型)。
5:reasonable:
分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
6:params:
为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值, 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero。
7:supportMethodsArguments:
支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTest 和 ArgumentsObjTest。
8:autoRuntimeDialect:
默认值为 false。设置为 true 时,允许在运行时根据多数据源自动识别对应方言的分页 (不支持自动选择sqlserver2012,只能使用sqlserver),用法和注意事项参考下面的场景五。
9:closeConn:
默认值为 true。当使用运行时动态数据源或没有设置 helperDialect 属性自动获取数据库类型时,会自动获取一个数据库连接, 通过该属性来设置是否关闭获取的这个连接,默认true关闭,设置为 false 后,不会关闭获取的连接,这个参数的设置要根据自己选择的数据源来决定。
1.2.3.4. 基本使用方法
PageHelper的基本使用有6种,大家可以查看文档,最常用的有两种
1.2.3.4.1. RowBounds方式的调用(了解)
List list = sqlSession.selectList(“x.y.selectIf”, null, new RowBounds(1, 10));
使用这种调用方式时,你可以使用RowBounds参数进行分页,这种方式侵入性最小,我们可以看到,通过RowBounds方式调用只是使用了这个参数,并没有增加其他任何内容。
分页插件检测到使用了RowBounds参数时,就会对该查询进行物理分页。
关于这种方式的调用,有两个特殊的参数是针对 RowBounds 的,你可以参看上面的分页插件参数介绍
注:不只有命名空间方式可以用RowBounds,使用接口的时候也可以增加RowBounds参数。
【操作步骤】
第一步:测试类:
// 测试PageHelper,RowBounds方式的调用(了解)
@Test
public void findAllRowBounds(){
RowBounds rowBounds = new RowBounds(0,2);
List list = productDao.findAllRowBounds(rowBounds);
for (Product product : list) {
System.out.println(product);
}
}
其中:
0表示从第1条记录开始检索
2表示每页最多显示2条记录
第二步:productDao.java
@Select(“select * from product”)
List findAllRowBounds(RowBounds rowBounds);
注意: 由于默认情况下的 RowBounds 无法获取查询总数,分页插件提供了一个继承自 RowBounds 的 PageRowBounds,这个对象中增加了 total 属性,执行分页查询后,可以从该属性得到查询总数。
// 测试PageHelper,RowBounds方式的调用(了解)
@Test
public void findAllRowBounds(){
PageRowBounds rowBounds = new PageRowBounds(2,2);
List list = productDao.findAllRowBounds(rowBounds);
System.out.println(“总记录数:”+rowBounds.getTotal());
for (Product product : list) {
System.out.println(product);
}
}
1.2.3.4.2. PageHelper.startPage 静态方法调用(重点)
这种方式是我们要掌握的
在你需要进行分页的 MyBatis 查询方法前调用PageHelper.startPage 静态方法即可,紧跟在这个方法后的第一个MyBatis 查询方法会被进行分页。
【步骤】
第一步:测试类:
// 测试PageHelper,PageHelper.startPage 静态方法调用(重点)
@Test
public void findAllPageHelper(){
PageHelper.startPage(1,2); // 从第1页开始检索,每页查询2条记录
List list = productDao.findAllProduct();
for (Product product : list) {
System.out.println(product);
}
}
第二步:productDao.java
@Select(“select * from product”)
public List findAllProduct();
1.2.3.4.3. PageInfo介绍
以下是PageHelper自带的分页对象,基本能满足我们平时工作的分页需求,等会我们就直接使用它。
public class PageInfo implements Serializable {
private static final long serialVersionUID = 1L;
//当前页
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,PageInfo介绍
@Test
public void findAllPageInfo(){
PageHelper.startPage(1,2); // 从第1页开始检索,每页查询2条记录
List list = productDao.findAllProduct();
PageInfo pageInfo = new PageInfo(list);
System.out.println(pageInfo);
for (Product product : list) {
System.out.println(product);
}
}