关键词: Mybatis 插件 分页
常见问题汇总
官方常见问题汇总
1.PageHelper.startPage不起作用
- 只有紧跟在 PageHelper.startPage 方法后的第一个 Mybatis 的查询(Select)方法会被分页
2.请不要配置多个分页插件
- 请不要在系统中配置多个分页插件(使用 Spring 时,mybatis-config.xml 和 Spring<bean> 配置方式,请选择其中一种,不要同时配置多个分页插件)!
3.分页插件不支持带有 for update 语句的分页
- 对于带有 for update 的 sql,会抛出运行时异常,对于这样的 sql 建议手动分页,毕竟这样的 sql 需要重视。
4.为什么不支持一对一和一对多结果映射的分页查询
- 在一对一和一对多时,根据分页条件查询出 100 条数据时,由于一对一和一对多会去重,经过嵌套处理后数据量会减少,因此分页想要获得 100 条数据无法实现。想要支持这种情况可以使用嵌套查询。嵌套查询是要额外执行SQL,主SQL可以得到正确的结果数量,因此可以正常分页。
配置参数使用
- 需要使用PageInfo类时,需要设置配置参数 rowBoundsWithCount 为 true,此时会在分页时进行count查询
- 当设置 offsetAsPageNum 为 true 时,可以在查询时使用pageNum,pageSize代替原有参数 offset,limit 便于理解
- 当设置 pageSizeZero 为 true 后,传入的 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果
- 当用户输入参数不合法时,希望得到边界页数时需要设置合理化参数 reasonable 为 true
推荐使用方式
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
//用PageInfo对结果进行包装
PageInfo page = new PageInfo(list);
避免不安全的分页
PageHelper 方法使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的
只要你可以保证在 PageHelper 方法调用后紧跟 MyBatis 查询方法,这就是安全的。因为 PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。
如果代码在进入 Executor 前发生异常,就会导致线程不可用,这属于人为的 Bug(例如接口方法和 XML 中的不匹配,导致找不到 MappedStatement 时), 这种情况由于线程不可用,也不会导致 ThreadLocal 参数被错误的使用。
如果PageHelper 生产了一个分页参数,但是没有被消费,这个参数就会一直保留在这个线程上。当这个线程再次被使用时,就可能导致不该分页的方法去消费这个分页参数,这就产生了莫名其妙的分页。
一点建议
- 1.一般前端传过来的pageNum 和 pageSize 建议有一个初始化的默认值(如1,10),这样即使前端忘记传递相应的值也不至于页面卡死。若前端想获取所有值时,可以放开pageSizeZero 参数 后传递 pageSize=0
- 2.前端分页一般都要求传递结果总数,因此一般情况下会将 rowBoundsWithCount 参数放开
- 3.若非必须,不建议将 reasonable 参数放开,一方面有违逻辑常识,另一方面可能难以发觉和定位隐藏的问题