使用JPA进行分页需要前台传入两个参数:start 和 count,其中 start 代表意思是第几页,count 代表的意思是是每页多少条记录。
@GetMapping("/latest?start= &count=") public List<SpuSimplifyVO> getLatestSpuList(@RequestParam(defaultValue = "0") Integer start, @RequestParam(defaultValue = "10") Integer count) { Mapper mapper = DozerBeanMapperBuilder.buildDefault(); Page<Spu> spuList = this.spuService.getLatestPagingSpu(start, count); List<SpuSimplifyVO> vos = new ArrayList<>(); /*for (Spu s : spuList) { SpuSimplifyVO vo = mapper.map(s, SpuSimplifyVO.class); vos.add(vo); }*/ spuList.forEach(s -> { SpuSimplifyVO vo = mapper.map(s, SpuSimplifyVO.class); vos.add(vo); }); return vos; }
这里涉及的就是 Page<Spu> spuList = this.spuService.getLatestPagingSpu(start, count); 这一句,这里调用 Service 中的 getLatestPagingSpu() ,Service 中的代码如下:
public Page<Spu> getLatestPagingSpu(Integer pageNum, Integer size) { PageRequest pageRequest = PageRequest.of(pageNum, size, Sort.by("createTime").descending()); return this.spuRepository.findAll(pageRequest); }
直接使用 PageRequest.of() 接收两个参数,第一个是查询第几页,第二个是每页显示的数量,第三个是可选参数,Soty.by() 进行排序,传入的是一个 Entity 中的字段名,返回一个 Page<T> 类型。
但是这里有一个问题需要注意,就是 start 是从 0 开始,传统中分页传入的参数是 page 和 pageSize 中的 page 是从 1 开始,这里可以编写一个工具类进行转换,首先我们创建一个BO类,PageCounter ,代码如下:
@Getter @Setter @Builder public class PageCounter { private Integer page; private Integer count; }
工具类 CommonUtil 代码如下:
public class CommonUtil { public static PageCounter convertToPageParameter(Integer start, Integer count) { int pageNum = start / count; return PageCounter.builder().page(pageNum).count(count).build(); } }
调用转换的时候,使用如下:
Page<Spu> spuList = this.spuService.getLatestPagingSpu(CommonUtil.convertToPageParameter(start, count).getPage(), count);
分页完成后,分页结果需要返回给前端是封装好的数据,如果直接返给前端一个 List<SpuSimplifyVO>这样的类,前端还是无法获取到总页数,当前页数等信息的,因此这里需要返给一个分页的类型数据结构给前端,因此这里定义一个 Paging 类用封装返给前端的数据,代码如下:
@Getter @Setter @NoArgsConstructor public class Paging<T> { private Long total; // 查询内容总数量 private Integer count; // 每页显示的数量 private Integer page; // 页码 private Integer totalPage; // 总页数 private List<T> items; // 每页显示的内容列表 public Paging(Page<T> pageT) { this.initPageParameters(pageT); this.items = pageT.getContent(); } void initPageParameters(Page<T> pageT) { this.total = pageT.getTotalElements(); this.count = pageT.getSize(); this.page = pageT.getNumber(); this.totalPage = pageT.getTotalPages(); } }
但是由于我们需要先获取到的是 Spu 的数据然后在通过 DozerBeanMapper 拷贝属性到 SpuSimplifyVO 中,所以这里我们如果直接使用 Paging 作为返回值,操作会非常复杂,因此我们定义一个新的 VO类 PagingDozer 让其继承 Paging
@Getter @Setter public class PagingDozer<T, K> extends Paging { @SuppressWarnings("unchecked") public PagingDozer(Page<T> tPage, Class<K> kClass) { this.initPageParameters(tPage); List<T> tList = tPage.getContent(); Mapper mapper = DozerBeanMapperBuilder.buildDefault(); List<K> voList = new ArrayList<>(); tList.forEach(t -> { K kVO = mapper.map(t, kClass); voList.add(kVO); }); this.setItems(voList); } }
调用代码,返回给前端
@GetMapping("/latest") public PagingDozer<Spu, SpuSimplifyVO> getLatestSpuList(@RequestParam(defaultValue = "0", name = "第几条记录(默认从0开始)") Integer start, @RequestParam(defaultValue = "10", name = "每一页几条记录") Integer count) { PageCounter pageCounter = CommonUtil.convertToPageParameter(start, count); Page<Spu> spuList = this.spuService.getLatestPagingSpu(pageCounter.getPage(), pageCounter.getCount()); return new PagingDozer<>(spuList, SpuSimplifyVO.class); }