PageHelper插件注意事项
-
使用PageHelper.startPage后要紧跟查询语句
下面的代码就有可能出问题:
PageHelper.startPage(10, 10); if(param != null) { List<Data> data = dataMapper.select(example); }
因为如果
param == null
,那么就会导致设置了分页插件但却没有执行查询,此时 PageHelper 已经在当前线程的 ThreadLocal 里面设置了分页参数,但是没有被消费,这个参数就会一直保存在这个线程里。当这个线程继续往后跑或者被复用时遇到一条 SQL 语句, 就可能会导致不该分页的方法去消费这个分页参数,导致预期之外的结果。所以上面的代码应该写出下面这样,保证使用分页插件后立即执行 SQL 语句。PageHelper.startPage(10, 10); List<Data> data = dataMapper.select(example);
这样就不会污染线程,PageHelper 插件内部会在执行完 SQL 语句后自动清除在 ThreadLocal 中存储的分页信息。
-
PageInfo获取分页信息
对于上面的代码,可以使用下面的代码获取分页信息:
PageInfo info = new PageInfo(data);
这是因为使用 PageHelper 后,mybatis 执行查询返回的 List 被 PageHelper 拦截处理了,最终返回的 List 是 Page 的子类,里面保存有分页信息,这点可以通过 PageInfo 的构造函数看出:
public PageInfo(List<? extends T> list, int navigatePages) { super(list); this.isFirstPage = false; this.isLastPage = false; this.hasPreviousPage = false; this.hasNextPage = false; if (list instanceof Page) { Page page = (Page)list; // 在这里打断点使用分页插件返回的List会通过该if判断 this.pageNum = page.getPageNum(); this.pageSize = page.getPageSize(); this.pages = page.getPages(); this.size = page.size(); if (this.size == 0) { this.startRow = 0L; this.endRow = 0L; } else { this.startRow = page.getStartRow() + 1L; this.endRow = this.startRow - 1L + (long)this.size; } } ... }
所以尽量不要修改分页插件返回的 List,否则通过 PageInfo 获取分页信息时会得到错误的信息。