Pagehelper分页插件,total 等于 pageSize问题

问题描述:

项目框架:ruoyi-vue

maven依赖

<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper-spring-boot-starter</artifactId>
  <version>1.4.6</version>
</dependency>

问题场景复现:

  • Controller层
@RestController
@RequestMapping("/system/config")
public class SysConfigController extends BaseController
{
    @GetMapping("/list")
    public TableDataInfo list(SysConfig config)
    {
        startPage();
        List<SysConfig> list = configService.selectConfigList(config);
        return getDataTable(list);
    }
 }
  • Service实现层(忽略接口定义)
@Override
    public List<SysConfig> selectConfigList(SysConfig config)
    {
        List<SysConfig> list = configMapper.selectConfigList(config);
        
        List<SysConfig> listNew = new ArrayList<SysConfig>();
        for(SysConfig sysConfig:list){
            sysConfig.setName()//进行相关业务处理
            listNew.add(sysConfig);
        }
        return listNew;
    }

 问题描述:

  按上述逻辑实现之后,PageInfototal属性值始终是传入的 pageSize值;

原因分析:

  • pagehelper插件中的部分源码:
public class PageSerializable<T> implements Serializable {
    //...省略

    @SuppressWarnings("unchecked")
    public PageSerializable(List<? extends T> list) {
        this.list = (List<T>) list;
        if(list instanceof Page){
            this.total = ((Page<?>)list).getTotal();
        } else {
            this.total = list.size();
        }
    }
    //...省略
}
  • 实现原理分析:

在分页业务中,我们最终返回的List数据集正常情况下是被包装成了Page实例,但是按照上述Service层的实现,最后返回的却是ArrayList实例,所以会进入源码中的else分支,因此最终返回的total是经过分页查询之后的结果集总数,也就是你传入的pageSize当前页的记录数;

解决方案:

  • 方案一
@RestController
@RequestMapping("/system/config")
public class SysConfigController extends BaseController
{
    @GetMapping("/list")
    public TableDataInfo list(SysConfig config)
    {
        startPage();
        List<SysConfig> list = configService.selectConfigList(config);
        //将Service的实现逻辑提取过来
        return getDataTable(list);
    }
 }

在不修改若依框架的实现方案的情况下,可以将简单的业务逻辑提取到Controller层(一般不是很推荐);这样Page对象始终在Controller业务所在的线程中,可以保证getDataTable方法中拿到的是最开始的Page对象;

  • 方案二
@RestController
@RequestMapping("/system/config")
public class SysConfigController extends BaseController
{
    @GetMapping("/list")
    public TableDataInfo list(SysConfig config)
    {
        Page page = startPage(); //为此方法添加返回值
        List<SysConfig> list = configService.selectConfigList(config);
        return getDataTable(list, page.toPageInfo()); //将上述的Page对象中的PageInfo对象传入
    }
 }

修改若依框架的方法实现,修改startPage(),增加Page返回值,修改getDataTable(),增加PageInfo入参。

posted @ 2022-12-30 15:54  shuangman  阅读(1287)  评论(0)    收藏  举报