1. 程式人生 > 實用技巧 >JPA 進行分頁處理

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);
    }