mybatis 中,使用 RowBounds 分页,非常方便,不需要在 sql 语句中写 limit,mybatis 会自动拼接 sql ,添加 limit最核心的是在 mapper 接口层,传参时传入 RowBounds(int offset, int limit) 对象,即可完成分页
offset:pageNum(第几页,能自动转到下一页)(若不配置pageHelper 则这个参数仍只是寻找下一条记录)
limit:pageSize(每一页展示记录数)
注意:由于 java 允许的最大整数为 2147483647,所以 limit 能使用的最大整数也是 2147483647,一次性取出大量数据可能引起内存溢出,所以在大数据场合慎重使用limit
结论:使用RowBounds最大好处就是节省了在xml再拼装limit 最好不用limit语句,而是搭配PageHelper使用RowBounds对象
1.引入github相关包
<dependency> //spring导入这个
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
<dependency> //springboot导入这个
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
2.配置application.yml
pagehelper:
helperDialect: mysql //自动检测当前的数据库链接,自动选择合适的分页方式 也即说明方言为mysql
reasonable: true //对页码小于0的时候有帮助
page-size-zero: true //当页码为0的时会查找所有记录
supportMethodsArguments: true
params: count=countSql
offset-as-page-num: true //将offset作为pagenum 即实现了自动翻页
3.重要提示
PageHelper.startPage方法重要提示
只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询(Select)方法会被分页。
请不要配置多个分页插件
请不要在系统中配置多个分页插件(使用Spring时,mybatis-config.xml和Spring配置方式,请选择其中一种,不要同时配置多个分页插件)!
分页插件不支持带有for update语句的分页
对于带有for update的sql,会抛出运行时异常,对于这样的sql建议手动分页,毕竟这样的sql需要重视。
分页插件不支持嵌套结果映射
由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。
4.代码实现
1.分页查询 不使用pagehelper
List<Route> routeList = routeMapper.findByPage(5, "%北京%", 0, 5);
sql语句(使用limit)及 mapper方法定义
@Select("select * from tab_route where cid = #{param1} AND rname LIKE #{param4} LIMIT #{param2} ,#{param3} ")
public List<Route> findByPage(int cid, int start, int pageSize, String rname);
2.使用pagehelper 带rowbound方式调用
List<Route> routeList = routeMapper.findByPage(5, "%北京%", new RowBounds(0, 5));
sql语句 及 mapper方法定义
@Select("select * from tab_route where cid = #{param1} AND rname LIKE #{param2} ")
public List<Route> findByPage(int cid, String rname, RowBounds rowBounds);
查询结果 rowBounds(0,5) 时和rowBounds(2,5)时 正如前面所说
若在application.yml 配置了offset-as-page-num = true 则会自动翻页
上图 1. rowBounds(0,5)
上图2
以上为rowBounds(2,5) 从数据库中可以看到 这是第6条及以后的记录 也就是第2页(因为第0页和第1页展示的内容相同 都是前五条记录)
- 分页查询采用PageHelper类 的能分页的方法PageHelper.startPage()
特征是紧跟着的第一个select方法会被分页(也不一定非得select开头 find开头也可 插件会自动判断是否是查询操作)
//分页查询采用PageHelper 能分页 /紧跟着的第一个select方法会被分页
PageHelper.startPage(2, 5);
List<Route> routeList = routeMapper.selectByPage(5, "%北京%");//考察是不是只有select开头的方法才可以 其实并不是
sql语句 及 mapper方法定义
@Select("select * from tab_route where cid = #{param1} AND rname LIKE #{param2} ")
List<Route> selectByPage(int cid, String rname);
图略 结果如上图1,2
- 分页查询采用参数方法调用
List<Route> routeList = routeMapper.findByPage(5, "%北京%", 0, 5);
sql语句 及其 mapper方法定义
//参数方法的方式调用
@Select("select * from tab_route where cid = #{param1} AND rname LIKE #{param2} ")
public List<Route> findByPage(
@Param("cid") int cid,
@Param("rname") String rname,
@Param("pageNum") int pageNum,
@Param("pageSize") int pageSize
);
图略 结果如上图1,2
此外 注意一点:
若不配置
offset-as-page-num: true
如
查询rowBounds(0,5) 时和rowBounds(2,5)时
或者 使用的是
PageHelper.offsetPage( );
如
查询 PageHelper.offsetPage(0, 5) 与PageHelper.offsetPage(2, 5)
那么查询的时候 并不会自动分页 而是只向下找2几条记录
上图 3. rowBounds(0,5)
上图4. rowBounds(2,5) 对比图2 可以明显看到 并没有分页 而是只往下找了两条记录
Bug:
带rowbound方法 和 参数方法的方式 同时存在时会报错
解决方案 选 带rowbound方法 和 参数方法的方式 其中一种方法二选一调用即可
参考:
重要提示