使用PageHelper出现的分页问题

今天突然出现一个bug,发现表格页卡出现问题了,选择一页显示50条数据,好着没问题,然后选显示10条,就出现问题了,分页功能不起作用了,等于说是返回给页面的total总数不对劲。

一顿操作debug之后,发现是执行sql语句返回的数据条数就是10条,当时我就纳闷了,这么简单的bug不应该是PageHelper出现的啊,毕竟好歹也是好多人用的分页插件呢。(后来发现是自己找问题的方向错了  -.-)

然后就吧问题瞄准了sql语句,后来折腾了半天,发现sql没啥问题。百思不得其解,头发都掉了几根,为了不掉头发,就百度吧。

百度出来发现问题不在sql,我们都知道PageHelper在startPage之后,等于是对下一次查询sql切面处理了。看了看代码:

PageHelper.startPage(demandScreening.getPage(), demandScreening.getSize());
List list =     
         procurementDemandService.procurementDemandList(demandScreening);
PageInfo pageInfo = new PageInfo(list);

没啥问题啊。

然后看到了这个:

https://blog.csdn.net/fchen_123/article/details/82881381

这个大佬说是因为对查询完sql的返回集合做了foreach操作,产生了不同的集合,然后就出现和我一样的问题了。

这时我才发现我其实也对集合进行排序,最后排序完的集合也是发现改变了。问题终于找到了。

//排序
list = list.stream()
           .sorted(Comparator.comparing(ProcurementDemandVo::getMaxDate).reversed())
           .collect(Collectors.toList());

上面那篇文章中大佬说有个

PagerCopyUtil.setPageInfo(retPageList,plist,clueInfoDTOList);

不过,我没找到。那就只能自己想办法了,不过问题找出来了,bug就等于解决一半了。

改成这样,就好了:

public PageInfo procurementDemandList(DemandScreening demandScreening) {
        List list = 
                     procurementDemandMapper.procurementDemandList(demandScreening);  
        //执行完sql,直接把结果给PageInfo
        PageInfo pageInfo = new PageInfo(list);
//...

        //接下来在进行排序
        //排序
        list = list.stream()
                .sorted(Comparator.comparing(ProcurementDemandVo::getMaxDate).reversed())
                .collect(Collectors.toList());

        //最后吧list集合替换掉
        pageInfo.setList(list);

        //只能返回PageInfo对象了
        return pageInfo;
    }

测试通过,没问题,就这样改。

可是为啥集合变了就出现问题了,这不应该啊,看看源码:
 

        super(list);
        this.isFirstPage = false;
        this.isLastPage = false;
        this.hasPreviousPage = false;
        this.hasNextPage = false;
        if (list instanceof Page) {
            Page page = (Page)list;
            this.pageNum = page.getPageNum();
            this.pageSize = page.getPageSize();
            this.pages = page.getPages();
            this.size = page.size();
            if (this.size == 0) {
                this.startRow = 0;
                this.endRow = 0;
            } else {
                this.startRow = page.getStartRow() + 1;
                this.endRow = this.startRow - 1 + this.size;
            }
            //pageNum,size,pageSize,startRow......
        } else if (list instanceof Collection) {
            this.pageNum = 1;
            this.pageSize = list.size();
            this.pages = this.pageSize > 0 ? 1 : 0;
            this.size = list.size();
            this.startRow = 0;
            this.endRow = list.size() > 0 ? list.size() - 1 : 0;
        }

        if (list instanceof Collection) {
            this.navigatePages = navigatePages;
            this.calcNavigatepageNums();
            this.calcPage();
            this.judgePageBoudary();
        }

调用了父类的构造函数。

public PageSerializable(List list) {
        this.list = list;
        
        if (list instanceof Page) {
            this.total = ((Page)list).getTotal();
        } else {
        //我们就是走了这一步,把size赋值给了total
            this.total = (long)list.size();
        }

    }

紧跟着PageHelper.startPage()方法第一个select语句会被分页,并吧返回对象改成一个Page对象,所以这里会判断list是否是Page对象。

问题找到了,也算是给自己一个教训吧,以后没事还是要看看源码理解理解思路。

 

转载:

PageHelper分页插件的源码分析

这位老哥写的很详细,想分析源码的可以参考参考他的文章。

 

你可能感兴趣的:(学习之旅)