最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

PageHelper中分頁失效的原因分析與正確方法實踐

 更新時間:2025年11月20日 09:06:59   作者:秧歌star519  
在使用 PageHelper 插件開發(fā)查詢接口時,有時會出現(xiàn)分頁失效的情況,下面小編就和大家詳細講講分頁失效的原因分析與正確方法,希望對大家有所幫助

1. 問題現(xiàn)象

在使用 PageHelper 插件開發(fā)查詢接口時,出現(xiàn)分頁失效的情況:接口返回了全部數(shù)據(jù)而非當前頁數(shù)據(jù),且 PageInfo 對象中的分頁元數(shù)據(jù)(如 total 總條數(shù)、pages 總頁數(shù))計算錯誤。

錯誤代碼示例

public BaseResponse<MyDataDTO> queryDataList(int pageNum, int pageSize, Map<String, Object> params) {
    BaseResponse response = new BaseResponse();
    
    // 1. 錯誤:在設(shè)置分頁參數(shù)前執(zhí)行了數(shù)據(jù)庫查詢
    List<MyDataDTO> dataList = myMapper.selectData(params);
    
    // 2. 判空邏輯
    if (!CollectionUtils.isEmpty(dataList)) {
        // 3. 錯誤:查詢早已完成,此時調(diào)用 startPage 無效
        PageHelper.startPage(pageNum, pageSize);
        
        // 4. 錯誤:直接使用全量 List 包裝 PageInfo,無法獲取數(shù)據(jù)庫真實總數(shù)
        PageInfo<MyDataDTO> pageInfo = new PageInfo<>(dataList);
        
        response.setResult(wrapPageResult(pageInfo));
        return response;
    }
    
    response.setResult(Collections.EMPTY_LIST);
    return response;
}

2. 原理分析

PageHelper 的核心機制基于 ThreadLocalMyBatis 攔截器(Interceptor)。

2.1 執(zhí)行流程

PageHelper 不是在內(nèi)存中對結(jié)果集進行截取,而是通過攔截器修改 SQL 語句。

設(shè)置參數(shù):調(diào)用 PageHelper.startPage(...) 時,插件會將分頁參數(shù)(pageNum, pageSize)存入當前線程的 ThreadLocal 中。

攔截 SQL:當 MyBatis 執(zhí)行 Mapper 方法時,PageHelper 攔截器會觸發(fā)。

SQL 改寫

  • 攔截器檢查 ThreadLocal 中是否存在分頁參數(shù)。
  • 若存在:攔截器會根據(jù)數(shù)據(jù)庫方言(如 MySQL)生成 SELECT COUNT(0) 語句獲取總數(shù),并將原 SQL 改寫為帶 LIMIT/OFFSET 的分頁 SQL 執(zhí)行。
  • 若不存在:攔截器直接放行,執(zhí)行原始 SQL。

清理上下文:SQL 執(zhí)行結(jié)束后,攔截器會清除 ThreadLocal 中的分頁參數(shù),避免污染后續(xù)查詢。

2.2 失效原因

在上述錯誤代碼中:

  • 執(zhí)行順序錯誤myMapper.selectDataPageHelper.startPage 之前執(zhí)行。
  • 攔截失敗:執(zhí)行查詢時,ThreadLocal 中沒有任何分頁參數(shù),攔截器未生效,MyBatis 執(zhí)行了全量查詢。
  • 參數(shù)無效:查詢結(jié)束后才調(diào)用 startPage,雖然設(shè)置了 ThreadLocal,但 SQL 交互已結(jié)束,該參數(shù)未被消費。
  • 元數(shù)據(jù)錯誤PageInfo 接收的是全量 List,因此它只能基于 List 的大小計算 total,導致分頁信息不符合預(yù)期。

3. 正確實現(xiàn)

核心原則PageHelper.startPage 必須緊鄰 Mapper 查詢方法之前調(diào)用。

修正代碼

public BaseResponse<MyDataDTO> queryDataList(int pageNum, int pageSize, Map<String, Object> params) {
    BaseResponse response = new BaseResponse();

    // 1. 設(shè)置分頁參數(shù)(存入 ThreadLocal)
    PageHelper.startPage(pageNum, pageSize);
    
    // 2. 執(zhí)行查詢(攔截器生效,自動改寫 SQL 并執(zhí)行 Count 查詢)
    // 注意:此時返回的 list 實際類型為 Page<E>
    List<MyDataDTO> dataList = myMapper.selectData(params);

    // 3. 獲取分頁結(jié)果
    PageInfo<MyDataDTO> pageInfo = new PageInfo<>(dataList);
    
    // 4. 結(jié)果處理(PageInfo 可安全處理空集合)
    if (!CollectionUtils.isEmpty(dataList)) {
         // pageInfo.getTotal() 為數(shù)據(jù)庫真實總數(shù)
         response.setResult(wrapPageResult(pageInfo));
    } else {
         response.setResult(Collections.EMPTY_LIST);
    }
    
    return response;
}

4. 最佳實踐與注意事項

嚴格遵守調(diào)用順序 必須保證 startPage -> Mapper查詢 -> PageInfo包裝 的執(zhí)行順序。

避免邏輯穿插 嚴禁在 startPageMapper查詢 之間插入其他 SQL 操作或復(fù)雜邏輯。

風險:PageHelper 的分頁參數(shù)是“一次性消費”的。如果在分頁查詢前插入了其他 SQL(如查詢用戶信息),分頁參數(shù)會被那條 SQL 消費掉,導致原本需要分頁的主查詢失效。

PageInfo 的健壯性 無需為了判空調(diào)整代碼順序。PageInfo 對空 List 有良好的兼容性,若查詢結(jié)果為空,它會自動設(shè)置 total=0,不會拋出異常。

大數(shù)據(jù)量風險 如果因順序錯誤導致分頁失效,全量查詢可能會將百萬級數(shù)據(jù)加載至內(nèi)存,極易引發(fā) OOM(內(nèi)存溢出),影響系統(tǒng)穩(wěn)定性。

到此這篇關(guān)于PageHelper中分頁失效的原因分析與正確方法實踐的文章就介紹到這了,更多相關(guān)PageHelper分頁失效解決內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot3整合Mybatis-plus3.5.3報錯問題解決

    Springboot3整合Mybatis-plus3.5.3報錯問題解決

    在日常學習springboot3相關(guān)的代碼時,在使用 SpringBoot3 整合 MyBatisplus 時出現(xiàn)了一些問題,花了不少時間處理,這篇文章主要介紹了Springboot3整合Mybatis-plus3.5.3報錯問題解決,需要的朋友可以參考下
    2023-11-11
  • Java MCP 鑒權(quán)設(shè)計與實現(xiàn)指南(完整示例)

    Java MCP 鑒權(quán)設(shè)計與實現(xiàn)指南(完整示例)

    MCP鑒權(quán)為大語言模型集成提供安全機制,涵蓋服務(wù)端過濾器、注解及客戶端Basic、Header、QueryString等方式,適配不同通信通道與框架,需遵循最佳實踐保障安全性,本文給大家介紹Java MCP 鑒權(quán)設(shè)計與實現(xiàn)指南,感興趣的朋友一起看看吧
    2025-07-07
  • MybatisPlus如何調(diào)用count函數(shù)

    MybatisPlus如何調(diào)用count函數(shù)

    這篇文章主要介紹了MybatisPlus如何調(diào)用count函數(shù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • String轉(zhuǎn)double失去精度問題及解決

    String轉(zhuǎn)double失去精度問題及解決

    這篇文章主要介紹了關(guān)于String轉(zhuǎn)double失去精度問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java字符串格式化功能?String.format用法詳解

    Java字符串格式化功能?String.format用法詳解

    String類的format()方法用于創(chuàng)建格式化的字符串以及連接多個字符串對象,熟悉C語言的同學應(yīng)該記得C語言的sprintf()方法,兩者有類似之處,format()方法有兩種重載形式
    2024-09-09
  • Java設(shè)計模式中的策略(Strategy)模式解讀

    Java設(shè)計模式中的策略(Strategy)模式解讀

    這篇文章主要介紹了Java設(shè)計模式中的策略(Strategy)模式解讀,對象的某個行為,在不同場景有不同實現(xiàn)方式,可以將這些行為的具體實現(xiàn)定義為一組策略,每個實現(xiàn)類實現(xiàn)一種策略,在不同場景使用不同的實現(xiàn),并且可以自由切換策略,需要的朋友可以參考下
    2023-10-10
  • Spring?Boot?Swagger3常用注解詳解與實戰(zhàn)指南

    Spring?Boot?Swagger3常用注解詳解與實戰(zhàn)指南

    Swagger是一個用于設(shè)計、構(gòu)建、文檔化和使用RESTful?Web服務(wù)的開源工具,Swagger3是Swagger的最新版本,它提供了許多新功能和改進,這篇文章主要介紹了Spring?Boot?Swagger3常用注解詳解與實戰(zhàn)指南的相關(guān)資料,需要的朋友可以參考下
    2025-10-10
  • Java多線程中的CyclicBarrier使用方法詳解

    Java多線程中的CyclicBarrier使用方法詳解

    這篇文章主要介紹了Java多線程中的CyclicBarrier使用方法詳解,CyclicBarrier是一種同步輔助工具,它允許一組線程都等待對方到達公共障礙點,在涉及固定大小的線程的程序中,CyclicBarriers非常有用,這些線程間必須相互等待,需要的朋友可以參考下
    2023-12-12
  • 分享7款開源Java反編譯工具

    分享7款開源Java反編譯工具

    今天我們要來分享一些關(guān)于Java的反編譯工具,反編譯聽起來是一個非常高上大的技術(shù)詞匯,通俗的說,反編譯是一個對目標可執(zhí)行程序進行逆向分析,從而得到原始代碼的過程。尤其是像.NET、Java這樣的運行在虛擬機上的編程語言,更容易進行反編譯得到源代碼
    2014-09-09
  • Springboot?接口需要接收參數(shù)類型是數(shù)組問題

    Springboot?接口需要接收參數(shù)類型是數(shù)組問題

    這篇文章主要介紹了Springboot?接口需要接收參數(shù)類型是數(shù)組問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評論

兴化市| 武川县| 开封市| 象州县| 美姑县| 思茅市| 望奎县| 策勒县| 西畴县| 桐庐县| 遵义县| 麻城市| 大连市| 遂宁市| 奉贤区| 成都市| 南投市| 正安县| 靖安县| 阿坝县| 胶南市| 纳雍县| 武鸣县| 佛教| 万宁市| 思南县| 建阳市| 万山特区| 布尔津县| 阳城县| 沅江市| 耿马| 桦甸市| 和平县| 孟连| 金华市| 义乌市| 军事| 临城县| 临沭县| 平顶山市|