Sping boot (二)—— 分頁功能的實現

Sping boot (二)—— 分頁功能的實現

分頁功能是一個spring boot項目常常用到的功能,所以這篇文章主要介紹一下兩種簡單的分頁。
其實從網上我們可以看到比較常用的分頁查詢方法是用Pageable插件,但是我並不會用這個東西(手動捂臉),其實也是自己沒去學的原因。所以這裏介紹兩種超級簡單的分頁查詢,一種是通過Page類實現,另一種是通過對結果集的手動分頁實現。

本文采用的例子便是筆者上一篇文章所寫

Page類實現分頁查詢

1、非條件查詢

UserRepository類裏面新增這樣一個方法:

Page<UserInfo> findAll(Pageable pageable);

然後來到UserController類裏面,新增分頁查詢接口:

//分頁查詢
    @GetMapping(value = "/page")
    private Page<UserInfo> findByPage(@RequestParam("pageNo")Integer pageNo, @RequestParam("pageSize")Integer pageSize){
        Page<UserInfo> page = userRepository.findAll(new PageRequest(pageNo,pageSize));   //pageNo從第幾頁開始查,pageSize頁面條數
        return page;
    }

這樣,我們調用這個接口所返回的便是已經分頁好的數據了,是不是超級簡單?讓我們來看看實際測試結果。
在這裏插入圖片描述
截圖不是很方便,實際結果如下:

{
    "content": [
        {
            "id": 1,
            "name": "小紅",
            "type": null
        },
        {
            "id": 2,
            "name": "小明",
            "type": null
        },
        {
            "id": 4,
            "name": "小軍",
            "type": null
        },
        {
            "id": 5,
            "name": "小強",
            "type": null
        },
        {
            "id": 6,
            "name": "小張",
            "type": null
        },
        {
            "id": 7,
            "name": "小李",
            "type": null
        },
        {
            "id": 8,
            "name": "小剛",
            "type": null
        },
        {
            "id": 9,
            "name": "小澤",
            "type": null
        },
        {
            "id": 10,
            "name": "小力",
            "type": null
        },
        {
            "id": 11,
            "name": "小總",
            "type": null
        }
    ],
    "pageable": {
        "sort": {
            "sorted": false,
            "unsorted": true,
            "empty": true
        },
        "offset": 0,
        "pageSize": 10,
        "pageNumber": 0,
        "unpaged": false,
        "paged": true
    },
    "totalElements": 11,
    "totalPages": 2,
    "last": false,
    "number": 0,
    "size": 10,
    "sort": {
        "sorted": false,
        "unsorted": true,
        "empty": true
    },
    "numberOfElements": 10,
    "first": true,
    "empty": false
}

可以看到,完整的結果裏面是有很多東西的,當然大部分我們是不需要的,我們只需要保留下content(第0頁的10條數據)、totalElements(總記錄條數)、totalPages(總頁數)、pageNumber(頁碼)、pageSize(頁面大小)這五種數據。那麼怎麼獲得它們呢?很簡單,用Page類自帶的方法就可以獲得了。

        page.getContent();
        page.getTotalElements();
        page.getTotalPages();
        page.getSize();
        page.getNumber();

這個時候我們再創建一個結果類,把需要的數據封裝到結果類裏面,由接口返回出來,就可以得到我們想要的結果了。
新建一個結果類ResultDto

public class ResultDto {
    private Integer pageNo;
    private Integer pageSize;
    private Long totalRecord;
    private Integer totalPage;
    private List<UserInfo> results;
    
    public ResultDto(){
        super();
    }
    
    public ResultDto(Integer pageNo, Integer pageSize, Long totalRecord, Integer totalPage, List<UserInfo> results){
        this.pageNo = pageNo;
        this.pageSize = pageSize;
        this.totalRecord = totalRecord;
        this.totalPage = totalPage;
        this.results = results;
    }
    
    public Integer getPageNo() {
        return pageNo;
    }

    public void setPageNo(Integer pageNo) {
        this.pageNo = pageNo;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Long getTotalRecord() {
        return totalRecord;
    }

    public void setTotalRecord(Long totalRecord) {
        this.totalRecord = totalRecord;
    }

    public Integer getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(Integer totalPage) {
        this.totalPage = totalPage;
    }

    public List<UserInfo> getResults() {
        return results;
    }

    public void setResults(List<UserInfo> results) {
        this.results = results;
    }
}

然後再修改一下分頁查詢的接口:

//分頁查詢
    @GetMapping(value = "/page")
    private ResultDto findByPage(@RequestParam("pageNo")Integer pageNo, @RequestParam("pageSize")Integer pageSize){
        Page<UserInfo> page = userRepository.findAll(new PageRequest(pageNo,pageSize));   //pageNo從第幾頁開始查,pageSize頁面條數
        ResultDto result = new ResultDto(page.getNumber(),page.getSize(),page.getTotalElements(),page.getTotalPages(),page.getContent());
        return result;
    }

最後運行一下,就會發現它返回的結果變成了這樣子:
在這裏插入圖片描述
這樣看上去就舒服了很多,不會有那麼多你不想要的信息,簡潔明瞭。這裏其實也就提到了一個結果類的思想,很多時候我們在調用接口時需要返回的信息是有要求的,這時我們就要自己建一個結果類來規範返回的信息。

  • 注意:參數pageNo和pageSize中pageNo是一個坑點,因爲一般我們是從第一頁開始查詢,但在java我們是從第0頁開始查詢,所以這裏就要注意你傳過來的參數值了,假如你是前後端分離開發的,那你就要跟前端商量好,傳過來的值是啥意思。
2、條件查詢

在entity類裏面新增一個type字段用於測試

    @Column(name = "type")
    private Integer type;

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

新增字段後記得手動去數據庫設置type值,然後在UserRepository類裏面新增這樣一個方法:

Page<UserInfo> findByType(Integer type,Pageable pageable);

接着在UserController類裏面新增接口:

    //條件分頁查詢
    @GetMapping(value = "/typepage")
    private ResultDto findByTypePage(@RequestParam("type")Integer type,@RequestParam("pageNo")Integer pageNo, @RequestParam("pageSize")Integer pageSize){
        Page<UserInfo> page = userRepository.findByType(type,new PageRequest(pageNo,pageSize));   //pageNo從第幾頁開始查,pageSize頁面條數
        ResultDto result = new ResultDto(page.getNumber(),page.getSize(),page.getTotalElements(),page.getTotalPages(),page.getContent());
        return result;
    }

最後運行測試一下,就可以得到結果了。
在這裏插入圖片描述
總結:條件分頁查詢和非條件分頁查詢其實屬於同一種方法,改變的只是增加了一個字段條件而已,這個分頁查詢方法也十分簡單,相信你們看一遍就會了。接下來講一個粗暴的分頁方法:分頁工具類。

分頁工具類實現查詢結果分頁

簡述:從之前的學習中我們知道,很多時候我們查詢出來的結果是一個List數組,而分頁無非就是將這個List數組進行再處理,分段罷了,當我們理解了分頁的本質之後,就可以製作這樣一個分頁工具類,手動對結果進行分頁。而分頁工具最大的優點就是查詢和分頁是分開的,這樣無論你做多複雜的查詢,只要是個List數組,我分頁工具就能把你分頁!
分頁工具類PageUtils

public class PageUtils<T> {
    //頁碼
    private int pageNo;
    //頁面大小
    private int pageSize;
    //總記錄條數
    private long totalRecord;
    //總頁數
    private int totalPage;
    //每頁的開始
    private int start;
    //當前頁面記錄集
    private List<T> results;

    public void doPage(List<T> lists){
        int count = lists.size();
        setTotalRecord(count);
        setTotalPage(count % pageSize == 0 ? count / pageSize : count / pageSize + 1);
        setStart(getPageNo() * getPageSize());
        setResults(lists.subList(getStart(),
                (count - getStart()) > getPageSize() ? getStart() + getPageSize() : count));
    }
    public PageUtils(){
        super();
    }
    public PageUtils(int pageNo, int pageSize){
        this.pageNo = pageNo;
        this.pageSize = pageSize;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public List<T> getResults() {
        return results;
    }

    public void setResults(List<T> results) {
        this.results = results;
    }

    public int getPageNo() {
        return pageNo;
    }

    public void setPageNo(int pageNo) {
        this.pageNo = pageNo;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public long getTotalRecord() {
        return totalRecord;
    }

    public void setTotalRecord(long totalRecord) {
        this.totalRecord = totalRecord;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }
}

寫好工具類之後,就可以直接到controller層UserController類裏面寫接口了:

@GetMapping(value = "/utilpage")
    private ResultDto findByUtil(@RequestParam("pageNo")Integer pageNo, @RequestParam("pageSize")Integer pageSize){
        PageUtils<UserInfo> page = new PageUtils<>(pageNo,pageSize);
        List<UserInfo> users = userRepository.findAll();
        page.doPage(users);
        ResultDto result = new ResultDto(page.getPageNo(),page.getPageSize(),
                page.getTotalRecord(),page.getTotalPage(),page.getResults());
        return result;
    }

運行一下,再postman裏面查看結果:
在這裏插入圖片描述
到此,關於分頁的兩個方法就介紹完了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章