JPA 進行分頁處理
使用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); }