得嘞,分頁插件PageHelper返回記錄總數total竟然出錯了!

問題描述

分頁返回的記錄總數total和每頁數量pageSize一致,數據庫統計的數量大於當前返回的總記錄數total,以下是相關代碼

問題分析

  1. sql錯誤導致返回信息有誤?
    檢查結果:經過數據執行日誌中生成的sql,sql正常並且數據總條數也正確

  2. PageHelper使用方式錯誤,導致數據錯誤
    檢查結果:通過與項目中其他地方使用記錄的對比,使用方式正確

  3. 返回結果後有中間處理導致總數減少
    檢查結果:網上有人遇到 對返回結果有類型轉化導致total錯誤的情況, 以此類推,發現當前代碼雖沒有對返回結果進行類型轉換但是對mapper返回的結果更換了實例對象然後將更換後的對象包裝,

    進一步查看包裝成PageInfo<T>時源碼並沒有關於total參數的處理,

    PageInfo<T>構造方法

    public class PageInfo<T> extends PageSerializable<T> {
    /**
     * 包裝Page對象
     *
     * @param list          page結果
     * @param navigatePages 頁碼數量
     */
    public PageInfo(List<T> list, int navigatePages) {
        super(list);
        if (list instanceof Page) {
            Page page = (Page) list;
            this.pageNum = page.getPageNum();
            this.pageSize = page.getPageSize();
    
            this.pages = page.getPages();
            this.size = page.size();
            //由於結果是>startRow的,所以實際的需要+1
            if (this.size == 0) {
                this.startRow = 0;
                this.endRow = 0;
            } else {
                this.startRow = page.getStartRow() + 1;
                //計算實際的endRow(最後一頁的時候特殊)
                this.endRow = this.startRow - 1 + this.size;
            }
        } else if (list instanceof Collection) {
            this.pageNum = 1;
            this.pageSize = list.size();
    
            this.pages = this.pageSize > 0 ? 1 : 0;
            this.size = list.size();
            this.startRow = 0;
            this.endRow = list.size() > 0 ? list.size() - 1 : 0;
        }
        if (list instanceof Collection) {
            this.navigatePages = navigatePages;
            //計算導航頁
            calcNavigatepageNums();
            //計算前後頁,第一頁,最後一頁
            calcPage();
            //判斷頁面邊界
            judgePageBoudary();
        }
    }
    }
    

    繼續查看父類PageSerializable,發現有關於total參數的處理,即mapper返回的list不是Page的實例時total會被設置爲返回list的size大小

    PageSerializable構造方法

    public PageSerializable(List<T> list) {
        this.list = list;
        if(list instanceof Page){
            this.total = ((Page)list).getTotal();
        } else {
            this.total = list.size();
        }
    }
    

    進一步debug,發現返回list確實不是Page類的實例,故推斷出這一結果是由於對mapper返回list結果更換了實例對象導致的,

    再次確認mapper返回結果,是Page的實例

解決方案

使用mapper返回的對象直接構造PageInfo對象,並在此基礎上獲取分頁信息

更正的代碼如下:

最佳實踐

在使用 PageInfo<T> pageInfo = new PageInfo<>(T); 構造PageInfo時直接使用mapper 返回對象,不要進行類型轉換或轉存等操作,以免丟失數據。

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