应用场景
在做公司项目的时候,在service层需要先调用存储过程获取sql然后再将sql放到Mapper中执行,得到List列表数据,并将其进行分页处理。
问题描述与分析
因为项目用的若依,所以理论上可以直接在Controller层使用startPage()这个静态方法,pageHelper插件就会自动帮你进行分页。但实际测试发现并没有分页。
后来断点发现分页的limit语句被拼接到了调用存储过程里面去了,原来startPage()方法只会对第一个执行的sql语句进行分页操作,所以当加入了startPage()方法后的第一个sql执行必须是你想要分页的查询,否则会导致分页失效或者报错。
由于我service实现层中是先调用存储过程获得查询sql后,再查询数据的,因此这个方法就不能直接在Controller层使用,因为service实现层进行了多个查询,随后我在service实现层中在调用查询数据的语句的上一句加入startPage()方法。但结果并没有预想的那样能够解决,结果仍然是分页失败,而且还报错了,在分页插件将分页条数LIMIT拼接到查询sql中的时候报错了。
通过断点调试发现参数都能拿到没啥问题,但是就是报错了,顿时有点百思不得其解。随后又查阅了下资料,发现可能是因为因为分页的结果集发生了改变的话,可能会导致分页失效。我的结果集确实是有改变的,我在查到数据后需要将数据进行一些脱敏处理,所以结果集改变了。
既然自动分页使用不了了,那我就手动进行分页,不在执行SQL的时候进行拼接做分页了,而是在查出数据后,再将其分页。
//手动分页
//通过request获取前端传来的pageNum和PageSize
PageDomain pageDomain = TableSupport.buildPageRequest();
Integer pageNum = pageDomain.getPageNum();
Integer pageSize = pageDomain.getPageSize();
int total = mapList.size();
//使用流操作,skip做记录跳转,limit限制条数
List<Map<String, String>> collect = mapList
.stream()
.skip((pageNum - 1) * pageSize)
.limit(pageSize)
.collect(Collectors.toList());
//计算总页数
int pageSum = total % pageSize == 0 ? total / pageSize : total /pageSize + 1;
PageHelper.startPage(pageNum,pageSize);
PageInfo<Map<String, String>> pageInfo = new PageInfo<>(collect);
//总记录数
pageInfo.setTotal(total);
//总页数
pageInfo.setPages(pageSum);
//清除分页缓存
PageHelper.clearPage();
return pageInfo;
分页操作完后,需要将缓存清除掉,否则下一个查询也会被当前的分页进行处理。
本篇就是记录下使用mybatis的分页插件遇到的一些小坑,虽然挺恶心人的,但是对pageHelper又有了更深一步的了解。