解决ruoyi框架中使用pagehelper插件分页查询后对数据进行对象转换后失效问题
一、场景重现
使用rouyi
框架时,可以看到很多分页查询,如:
//-----------SysConfigController-------------
@GetMapping("/list")
public TableDataInfo list(SysConfig config) {
startPage();
List<SysConfig> list = configService.selectConfigList(config);
return getDataTable(list);
}
//-----------SysConfigServiceImpl-------------
@Override
public List<SysConfig> selectConfigList(SysConfig config) {
return configMapper.selectConfigList(config);
}
这里的分页就是使用pagehelper
,很方便易用。
但如果需要将对象进行转换时,分页会失效,如:
//---------OrderController------------
@GetMapping("/list")
public TableDataInfo list(OrderDTO dto) {
startPage();
List<OrderDTO> list = orderService.selectOrderList(dto);
return getDataTable(list);
}
//---------OrderServiceImpl------------
@Override
public List<OrderDTO> selectOrderList(OrderDTO dto) {
List<OrderDO> list = orderMapper.selectOrderList(dto);
return list.stream().map(OrderDO::toDTO).collect(Collectors.toList());
}
此时会丢失total
属性,导致无法正常分页。
二、方案一
请看代码:
//---------OrderController------------
@GetMapping("/list")
public TableDataInfo list(OrderDTO dto) {
startPage();
List<OrderDO> list = orderService.selectOrderList(dto);
Page<OrderDTO> page = new Page<>();
//赋值 pageSize、pageNum、total
BeanUtils.copyProperties(list, page);
page.clear();
list.stream().map(OrderDO::toDTO).forEach(page::add);
//或 list.forEach(item->page.add(item.toDTO()));
//或 page.addAll(list.stream().map(OrderDO::toDTO).collect(Collectors.toList()));
return getDataTable(page);
}
//---------OrderServiceImpl------------
@Override
public List<OrderDO> selectOrderList(OrderDTO dto) {
return orderMapper.selectOrderList(dto);
}
上面的代码可以简化一下,先抽离公共部分
protected <T, R> Page<R> converter(List<T> list, Function<T, R> converter) {
Page<R> page = new Page<>();
BeanUtils.copyProperties(list, page);
page.clear();
list.stream().map(converter).forEach(page::add);
return page;
}
再进行改造
//---------OrderController------------
@GetMapping("/list")
public TableDataInfo list(OrderDTO dto) {
startPage();
List<OrderDO> list = orderService.selectOrderList(dto);
Page<OrderDTO> page = converter(list, OrderDO::toDTO);
return getDataTable(page);
}
Page
类继承了ArrayList
,看源码
package com.github.pagehelper;
import ... ...
public class Page<E> extends ArrayList<E> implements Closeable {
... ...
}
所以可以直接使用BaseController
中的getDataTable
方法
//----------BaseController-------------
protected TableDataInfo getDataTable(List<?> list) {
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setRows(list);
rspData.setMsg("查询成功");
rspData.setTotal(new PageInfo(list).getTotal());
return rspData;
}
也可以自己重载一下该方法
protected TableDataInfo convertDataTable(Page<?> page) {
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setRows(page.getResult());
rspData.setMsg("查询成功");
rspData.setTotal(page.getTotal());
return rspData;
}
三、方案二
还有另外一种方案,与这个大差不差,就是自定义一个分页类
import lombok.Data;
import java.util.List;
@Data
public class PageResult<T> {
//状态码 0:成功 其他:失败
private Integer code = 0;
//页码
private int pageNum;
//分页大小
private int pageSize;
//总数
private long total;
//返回数据
private List<T> data;
//构造函数
public PageResult(Integer code, PageLink pageLink, List<T> data) {
this.code = code;
this.pageNum = pageLink.getPageNum();
this.pageSize = pageLink.getPageSize();
this.total= pageLink.getTotal();
this.data = data;
}
public static <T> PageResult success(PageLink pageLink, List<T> data) {
return new PageResult<>(ResponseCode.OK, pageLink, data);
}
}
接收前端的分页传值
@Data
public class PageLink {
private int pageNum = 1;
private int pageSize = 10;
private long total;
}
//---------OrderController------------
@GetMapping(value = "/list")
public PageResult<OrderDTO> list(OrderDTO dto, PageLink pageLink) {
List<OrderDTO> list = orderService.selectOrderList(dto, pageLink);
return PageResult.success(pageLink, list);
}
//---------OrderServiceImpl------------
@Override
public List<OrderDTO> selectOrderList(OrderDTO dto, PageLink pageLink) {
// 分页查询
PageInfo<OrderDO> pageInfo = PageHelper.startPage(pageLink.getPageNum(), pageLink.getPageSize()).doSelectPageInfo(() -> orderMapper.selectOrderList(dto));
pageLink.setTotal(pageInfo.getTotal());
return pageInfo.getList().stream().map(OrderDO::toDTO).collect(Collectors.toList());
}