mybatis的分页pagehelper分页使用
PageHelper大概是我见过最“懒”的分页插件了。别的使用分页方案得写limit、count、分页封装Page对象,使用它倒好,分页一行静态方法调用,使用分页就完事了。分页但懒归懒,使用坑也不少。分页
先看最基础的使用用法。你只要在查询前调用PageHelper.startPage(pageNum,分页 pageSize),然后紧接着执行你的使用Mapper查询,PageHelper就会自动拦截这条SQL,分页拼接limit语句,使用并且额外执行一条count查询。分页返回的List其实是个Page对象,能直接拿到总记录数。
PageHelper.startPage(1, 10); List<User> users = userMapper.selectAll(); PageInfo<User> pageInfo = new PageInfo<>(users); // pageInfo.getTotal() 总条数 // pageInfo.getList() 当前页数据 注意那个“紧接着”三个字。我见过有人在这中间插了个if判断,或者调用了别的查询,结果分页直接失效。这玩意儿原理是ThreadLocal,它会把分页参数存到当前线程里,然后拦截器在下一个查询前消费掉。你要是中间隔了别的操作,参数就可能被别的查询吃掉,或者干脆不生效。
再说说排序。PageHelper支持排序参数,但别跟分页参数混在一起传。官方推荐用PageHelper.startPage(pageNum, pageSize, orderBy),但这个orderBy是字符串拼接,有SQL注入风险。我建议排序还是写死在SQL里,或者用白名单校验后再传。别图省事。
真正让人头疼的是多表关联查询。PageHelper对单表查询很友好,但一旦你用了collection或者association做嵌套结果映射,分页就虚了。它会先count再limit,但limit是在外层查询上做的,如果一对多映射,一页10条记录可能映射出30条数据,因为每个主记录带了好几个子记录。这时候得用PageHelper.startPage配合子查询分页,或者干脆手动分页,别硬上插件。
还有个细节——PageInfo和Page的区别。很多人搞混,其实Page只是List的一个实现,数据就在里面。PageInfo是对Page的包装,额外提供了页码、总页数、是否有上一页下一页这些导航信息。你要是只想要数据,直接拿List就行,不用非得转PageInfo。
最后提个性能问题。PageHelper默认会执行count查询,这在大表上可能很慢。你可以在startPage时传入count=false来跳过count,但前提是你不需要总条数。或者用PageHelper.clearPage()手动清理ThreadLocal,防止参数泄漏到下一个请求——虽然每次查询后它会自动清理,但你要是用了异步线程或者异常没抛出,就可能出问题。
说到底,PageHelper适合中小型项目,快速迭代用着很爽。但你要是搞大数据量或者复杂SQL,还是老老实实手写分页吧。工具是给人省事的,不是给人添堵的。

喜欢
讨厌