Mybatis-PageHelper官⽅使⽤⽂档
使⽤⽅法
1. 引⼊分页插件
引⼊分页插件有下⾯2种⽅式,推荐使⽤ Maven ⽅式。
1). 引⼊ Jar 包
你可以从下⾯的地址中下载最新版本的 jar 包
由于使⽤了sql 解析⼯具,你还需要下载 jsqlparser.jar(需要和PageHelper 依赖的版本⼀致) :
com.github.pagehelper pagehelper 最新版本 最新版本号可以从⾸页查看。
2. 配置插件
特别注意,新版是 com.github.pagehelper.PageInterceptor。 com.github.pagehelper.PageHelper 现在是⼀个特殊的dialect 实现类,是分页插件的默认实现类,提供了和以前相同的⽤法。
3. 在 MyBatis 配置 xml 中配置插件
2. 在 Spring 配置⽂件中配置插件 使⽤ spring 的属性配置⽅式,可以使⽤ plugins 属性像下⾯这样配置: params=value1
3. 分页插件参数介绍 分页插件提供了多个可选参数,这些参数使⽤时,按照上⾯两种配置⽅式中的⽰例配置即可。
分页插件可选参数如下:
dialect:默认情况下会使⽤ PageHelper ⽅式进⾏分页,如果想要实现⾃⼰的分页逻辑,可以实现
Dialect(com.github.pagehelper.Dialect) 接⼝,然后配置该属性为实现类的全限定名称。
下⾯⼏个参数都是针对默认 dialect 情况下的参数。使⽤⾃定义 dialect 实现时,下⾯的参数没有任何作⽤。
helperDialect:分页插件会⾃动检测当前的数据库链接,⾃动选择合适的分页⽅式。 你可以配置helperDialect属性来指定分页插件使⽤哪种⽅⾔。配置时,可以使⽤下⾯的缩写值:
oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby
特别注意:使⽤ SqlServer2012 数据库时,需要⼿动指定为 sqlserver2012,否则会使⽤ SqlServer2005 的⽅式进⾏分页。
你也可以实现 AbstractHelperDialect,然后配置该属性为实现类的全限定名称即可使⽤⾃定义的实现⽅法。
offsetAsPageNum:默认值为 false,该参数对使⽤ RowBounds 作为分页参数时有效。 当该参数设置为 true 时,会将 RowBounds 中的 offset 参数当成 pageNum 使⽤,可以⽤页码和页⾯⼤⼩两个参数进⾏分页。
rowBoundsWithCount:默认值为false,该参数对使⽤ RowBounds 作为分页参数时有效。 当该参数设置为true时,使⽤ RowBounds 分页会进⾏ count 查询。
pageSizeZero:默认值为 false,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果(相当于没有执⾏分页查询,但是返回结果仍然是 Page 类型)。
reasonable:分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第⼀页, pageNum>pages(超过总数时),会查询最后⼀页。默认false 时,直接根据参数进⾏查询。
params:为了⽀持startPage(Object params)⽅法,增加了该参数来配置参数映射,⽤于从对象中根
据属性名取值, 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的⽤默认值, 默认值为
pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero。
supportMethodsArguments:⽀持通过 Mapper 接⼝参数来传递分页参数,默认值false,分页插件会从查询⽅法的参数值中,⾃动根据上⾯ params 配置的字段中取值,查到合适的值时就会⾃动分页。 使⽤⽅法可以参考测试代码中的
com.st.basic 包下的 ArgumentsMapTest 和 ArgumentsObjTest。
autoRuntimeDialect:默认值为 false。设置为 true 时,允许在运⾏时根据多数据源⾃动识别对应⽅⾔的分页 (不⽀持⾃动选择sqlserver2012,只能使⽤sqlserver),⽤法和注意事项参考下⾯的场景五。
closeConn:默认值为 true。当使⽤运⾏时动态数据源或没有设置 helperDialect 属性⾃动获取数据库类型时,会⾃动获取⼀个数据库连接, 通过该属性来设置是否关闭获取的这个连接,默认true关闭,设置为 false 后,不会关闭获取的连接,这个参数的设置要根据⾃⼰选择的数据源来决定。
aggregateFunctions(5.1.5+):默认为所有常见数据库的聚合函数,允许⼿动添加聚合函数(影响⾏数),所有以聚合函数开头的函数,在进⾏ count 转换时,会套⼀层。其他函数和列会被替换为 coun
t(0),其中count列可以⾃⼰配置。
重要提⽰:
当 offsetAsPageNum=false 的时候,由于 PageNum 问题,RowBounds查询的时候 reasonable 会强制为 false。使⽤PageHelper.startPage ⽅法不受影响。
4. 如何选择配置这些参数
单独看每个参数的说明可能是⼀件让⼈不爽的事情,这⾥列举⼀些可能会⽤到某些参数的情况。
场景⼀
如果你仍然在⽤类似ibatis式的命名空间调⽤⽅式,你也许会⽤到rowBoundsWithCount, 分页插件对RowBounds⽀持和 MyBatis 默认的⽅式是⼀致,默认情况下不会进⾏ count 查询,如果你想在分页查询时进⾏ count 查询, 以及使⽤更强⼤的 PageInfo 类,你需要设置该参数为 true。
注: PageRowBounds 想要查询总数也需要配置该属性为 true。
场景⼆
如果你仍然在⽤类似ibatis式的命名空间调⽤⽅式,你觉得 RowBounds 中的两个参数 offset,limit 不如 pageNum,pageSize 容易理解,你可以使⽤ offsetAsPageNum 参数,将该参数设置为 true 后,offset会当成 pageNum 使⽤,limit 和 pageSize 含义相同。
场景三
如果觉得某个地⽅使⽤分页后,你仍然想通过控制参数查询全部的结果,你可以配置 pageSizeZero 为 true, 配置后,当 pageSize=0
或者 RowBounds.limit = 0 就会查询出全部的结果。
场景四
如果你分页插件使⽤于类似分页查看列表式的数据,如新闻列表,软件列表, 你希望⽤户输⼊的页数不在合法范围(第⼀页到最后⼀页之外)时能够正确的响应到正确的结果页⾯, 那么你可以配置 reasonable 为 true,这时如果 pageNum<=0 会查询第⼀页,如果pageNum>总页数 会查询最后⼀页。
场景五
如果你在 Spring 中配置了动态数据源,并且连接不同类型的数据库,这时你可以配置 autoRuntimeDialect 为 true,这样在使⽤不同数据源时,会使⽤匹配的分页进⾏查询。 这种情况下,你还需要特别注意 closeConn 参数,由于获取数据源类型会获取⼀个数据库连接,所以需要通过这个参数来控制获取连接后,是否关闭该连接。 默认为 true,有些数据库连接关闭后就没法进⾏后续的数据库操作。⽽有些数据库连接不关闭就会很快由于连接数⽤完⽽导致数据库⽆响应。所以在使⽤该功能时,特别需要注意你使⽤的数据源是否需要关闭数据库连接。
当不使⽤动态数据源⽽只是⾃动获取 helperDialect 时,数据库连接只会获取⼀次,所以不需要担⼼占⽤的这⼀个连接是否会导致数据库出错,但是最好也根据数据源的特性选择是否关闭连接。
3. 如何在代码中使⽤
阅读前请注意看重要提⽰
分页插件⽀持以下⼏种调⽤⽅式:
//第⼀种,RowBounds⽅式的调⽤
List list = sqlSession.selectList(“x.y.selectIf”, null, new RowBounds(0, 10));
//第⼆种,Mapper接⼝⽅式的调⽤,推荐这种使⽤⽅式。
PageHelper.startPage(1, 10);
List list = countryMapper.selectIf(1);
//第三种,Mapper接⼝⽅式的调⽤,推荐这种使⽤⽅式。
PageHelper.offsetPage(1, 10);
List list = countryMapper.selectIf(1);
//第四种,参数⽅法调⽤
//存在以下 Mapper 接⼝⽅法,你不需要在 xml 处理后两个参数
public interface CountryMapper {
List selectByPageNumSize(
@Param(“user”) User user,
@Param(“pageNum”) int pageNum,
@Param(“pageSize”) int pageSize);
}
//配置supportMethodsArguments=true
//在代码中直接调⽤:
List list = countryMapper.selectByPageNumSize(user, 1, 10);
//第五种,参数对象
//如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页
//有如下 User 对象
public class User {
//其他fields
//下⾯两个参数名和 params 配置的名字⼀致
private Integer pageNum;
private Integer pageSize;
}
//存在以下 Mapper 接⼝⽅法,你不需要在 xml 处理后两个参数
public interface CountryMapper {
List selectByPageNumSize(User user);
}
//当 user 中的 pageNum!= null && pageSize!= null 时,会⾃动分页
List list = countryMapper.selectByPageNumSize(user);
//第六种,ISelect 接⼝⽅式
//jdk6,7⽤法,创建接⼝
Page page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() {
@Override
public void doSelect() {
countryMapper.selectGroupBy();
}
});
//jdk8 lambda⽤法
Page page = PageHelper.startPage(1, 10).doSelectPage(()-> countryMapper.selectGroupBy());
//也可以直接返回PageInfo,注意doSelectPageInfo⽅法和doSelectPage
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() {
@Override
public void doSelect() {
countryMapper.selectGroupBy();
}
});
//对应的lambda⽤法
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> countryMapper.selectGroupBy());
//count查询,返回⼀个查询语句的count数
long total = unt(new ISelect() {
@Override
public void doSelect() {
countryMapper.selectLike(country);
}
});
//lambda
total = unt(()->countryMapper.selectLike(country));
下⾯对最常⽤的⽅式进⾏详细介绍
1). RowBounds⽅式的调⽤
List list = sqlSession.selectList(“x.y.selectIf”, null, new RowBounds(1, 10));
使⽤这种调⽤⽅式时,你可以使⽤RowBounds参数进⾏分页,这种⽅式侵⼊性最⼩,我们可以看到,通过RowBounds⽅式调⽤只是使⽤了这个参数,并没有增加其他任何内容。
分页插件检测到使⽤了RowBounds参数时,就会对该查询进⾏物理分页。
关于这种⽅式的调⽤,有两个特殊的参数是针对 RowBounds 的,你可以参看上⾯的 场景⼀ 和 场景⼆
分页查询插件
注:不只有命名空间⽅式可以⽤RowBounds,使⽤接⼝的时候也可以增加RowBounds参数,例如:
//这种情况下也会进⾏物理分页查询
List selectAll(RowBounds rowBounds);
注意: 由于默认情况下的 RowBounds ⽆法获取查询总数,分页插件提供了⼀个继承⾃ RowBounds 的 PageRowBounds,这个对象中增加了 total 属性,执⾏分页查询后,可以从该属性得到查询总数。
2). PageHelper.startPage 静态⽅法调⽤
除了 PageHelper.startPage ⽅法外,还提供了类似⽤法的 PageHelper.offsetPage ⽅法。
在你需要进⾏分页的 MyBatis 查询⽅法前调⽤ PageHelper.startPage 静态⽅法即可,紧跟在这个⽅法后的第⼀个MyBatis 查询⽅法会被进⾏分页。
例⼀:
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
//紧跟着的第⼀个select⽅法会被分页
List list = countryMapper.selectIf(1);
assertEquals(2, (0).getId());
assertEquals(10, list.size());
//分页时,实际返回的结果list类型是Page,如果想取出分页信息,需要强制转换为Page
assertEquals(182, ((Page) list).getTotal());
例⼆:
//request: url?pageNum=1&pageSize=10
//⽀持 ServletRequest,Map,POJO 对象,需要配合 params 参数
PageHelper.startPage(request);
//紧跟着的第⼀个select⽅法会被分页
List list = countryMapper.selectIf(1);
//后⾯的不会被分页,除⾮再次调⽤PageHelper.startPage
List list2 = countryMapper.selectIf(null);
//list1
assertEquals(2, (0).getId());
assertEquals(10, list.size());
//分页时,实际返回的结果list类型是Page,如果想取出分页信息,需要强制转换为Page,
//或者使⽤PageInfo类(下⾯的例⼦有介绍)
assertEquals(182, ((Page) list).getTotal());
//list2
assertEquals(1, (0).getId());
assertEquals(182, list2.size());
例三,使⽤PageInfo的⽤法:
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
List list = countryMapper.selectAll();
//⽤PageInfo对结果进⾏包装
PageInfo page = new PageInfo(list);
//测试PageInfo全部属性
//PageInfo包含了⾮常全⾯的分页属性
assertEquals(1, PageNum());
assertEquals(10, PageSize());
assertEquals(1, StartRow());
assertEquals(10, EndRow());
assertEquals(183, Total());
assertEquals(19, Pages());
assertEquals(1, FirstPage());
assertEquals(8, LastPage());
assertEquals(true, page.isFirstPage());
assertEquals(false, page.isLastPage());
assertEquals(false, page.isHasPreviousPage());
assertEquals(true, page.isHasNextPage());
3). 使⽤参数⽅式
想要使⽤参数⽅式,需要配置 supportMethodsArguments 参数为 true,同时要配置 params 参数。 例如下⾯的配置:
在 MyBatis ⽅法中:
List selectByPageNumSize(
@Param(“user”) User user,
@Param(“pageNumKey”) int pageNum,
@Param(“pageSizeKey”) int pageSize);
当调⽤这个⽅法时,由于同时发现了 pageNumKey 和 pageSizeKey 参数,这个⽅法就会被分页。params 提供的⼏个参数都可以这样使⽤。
除了上⾯这种⽅式外,如果 User 对象中包含这两个参数值,也可以有下⾯的⽅法:
List selectByPageNumSize(User user);
当从 User 中同时发现了 pageNumKey 和 pageSizeKey 参数,这个⽅法就会被分页。
注意:pageNum 和 pageSize 两个属性同时存在才会触发分页操作,在这个前提下,其他的分页参数才会⽣效。
3). PageHelper 安全调⽤

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。