以前写mybatis分页,先要写一个count查询,然后再写一个真正分页查询的语句,效率比较低
List<RentDO> list = rentDAO.selectByPage(paramVO, sqlStr, status, (pageIndex - 1) * pageSize, pageSize);
PageVO<RentDO> pageVO = new PageVO<>();
pageVO.setTotal(rentDAO.count(paramVO, sqlStr, status));
pageVO.setRows(list);
后来找到了插件PageHelper可以省去写count的过程github地址
一、使用
配置
pagehelper.helperDialect=oracle
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql
pagehelper.page-size-zero=true
代码
Page<CustomerInfoListDO> pageInfo= PageHelper.startPage(pageIndex, pageSize);
List<CustomerInfoListDO> selectByPage = customerDAO.selectByFilter(queryParamsVO);
PageVO<CustomerInfoListDO> page = new PageVO<>();
page.setTotal((int)pageInfo.getTotal());
page.setRows(selectByPage);
二、需要注意的地方
PageHelper插件对mybatis执行流程进行了增强,添加了limit以及count查询,属于物理分页。
使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的。所以只要你可以保证在 PageHelper 方法调用后紧跟 MyBatis 查询方法,这就是安全的。因为 PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。
代码不贴了,源码里都有。
1.代码顺序
在利用PageHelper.startPage(page, rows)做分页时,应该写在查询之前,否则得到的total始终为0。
2.线程安全
PageHelper.startPage(pageIndex, pageSize);
List<CustomerInfoListDO> selectByPage;
if(queryParamsVO!= null){
selectByPage = customerDAO.selectByFilter(queryParamsVO);
} else {
selectByPage = new ArrayList<CustomerInfoListDO>();
}
这种情况下由于 queryParamsVO存在 null 的情况,就会导致 PageHelper 生产了一个分页参数,但是没有被消费,这个参数就会一直保留在这个线程上。当这个线程再次被使用时,就可能导致不该分页的方法去消费这个分页参数,这就产生了莫名其妙的分页。
可以这么写
List<CustomerInfoListDO> selectByPage;
if(queryParamsVO!= null){
PageHelper.startPage(pageIndex, pageSize);
selectByPage = customerDAO.selectByFilter(queryParamsVO);
} else {
selectByPage = new ArrayList<CustomerInfoListDO>();
}