切換語言為:簡體

MyBatis Plus 與 PageHelper 分頁外掛相容性問題解析與解決方案

  • 爱糖宝
  • 2024-11-18
  • 2029
  • 0
  • 0

在Java開發中,MyBatis Plus和PageHelper都是非常流行的MyBatis擴充套件外掛,它們分別提供了便捷的查詢封裝和分頁功能。許多開發者在專案中同時使用這兩個外掛時,常會遇到分頁資訊不準確的問題。本文將從常見問題現象出發,分析原因,並提供有效的解決方案,以幫助大家在開發中更好地使用這兩個外掛。

問題現象

在專案中,我們期望透過PageHelper來分頁查詢資料,並配合MyBatis Plus的LambdaQueryWrapper進行條件查詢。例如:

int pageNum = 2;
int pageSize = 2;

// 配置分頁引數
PageHelper.startPage(pageNum, pageSize);

// 使用 MyBatis Plus 的查詢封裝
LambdaQueryWrapper<DataPerson> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DataPerson::getDelFlag, DelFlagEnum.NORMAL.getCode());

// 使用 selectVoList 查詢
List<DataPersonVO> oldPersons = mapper.selectVoList(wrapper);
PageInfo<DataPersonVO> pageInfo = new PageInfo<>(oldPersons);
System.out.println(pageInfo);

按預期,pageInfo中應該顯示正確的分頁資訊,但實際輸出顯示 pageNum 一直是 1isLastPage 總是 true,分頁不生效。進一步分析SQL發現,selectVoList方法在資料庫查詢時確實被正確加上了LIMIT分頁引數,因此資料集是正確的,但分頁物件 PageInfopageNum 等屬性卻不正確。

原因分析

PageHelper在MyBatis攔截層新增分頁引數,以自動修改生成的SQL。但它的分頁上下文資訊捕獲依賴於標準MyBatis查詢,而MyBatis Plus的selectVoList等擴充套件方法生成SQL的方式有所不同,導致PageHelper在生成PageInfo時沒有正確捕獲pageNum等分頁上下文。

具體原因包括:

  1. PageHelper的分頁攔截機制:PageHelper依賴於MyBatis生成的SQL查詢,以自動在SQL中新增分頁引數並生成分頁物件,但某些MyBatis Plus特有方法如selectVoList不一定符合這種機制,可能會導致分頁引數未被正確傳遞。

  2. PageHelper和MyBatis Plus方法的相容性問題:儘管PageHelper能在查詢中加入分頁引數,但對於MyBatis Plus的擴充套件方法(如selectVoList),分頁上下文可能未正確傳遞到PageInfo中,導致頁面資料不一致。

解決方案

針對以上問題,我們可以考慮以下幾種解決方案:

方案一:使用MyBatis Plus自帶的分頁外掛

MyBatis Plus自帶了分頁外掛,完全支援MyBatis Plus擴充套件方法如selectVoList,適配性更高,可以確保分頁查詢和分頁資訊的一致性。具體步驟如下:

  1. 確保專案中已配置了MyBatis Plus的分頁外掛,例如在Spring Boot專案中引入PaginationInterceptor

  2. 使用MyBatis Plus的Page物件來進行分頁查詢:

    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    
    int pageNum = 2;
    int pageSize = 2;
    
    // 使用 MyBatis Plus 的分頁物件
    Page<DataPersonVO> page = new Page<>(pageNum, pageSize);
    
    // 執行分頁查詢
    page = mapper.selectVoList(page, wrapper);
    
    // 獲取分頁資訊
    long total = page.getTotal(); // 總記錄數
    long totalPages = page.getPages(); // 總頁數
    List<DataPersonVO> data = page.getRecords(); // 當前頁資料

使用MyBatis Plus的分頁外掛可以確保分頁資料準確,包括pageNumisLastPage等分頁資訊正確顯示。

方案二:自定義Mapper方法

如果由於專案限制,無法更換為MyBatis Plus分頁外掛,可以選擇在Mapper中自定義方法,透過編寫SQL語句,避免MyBatis Plus的擴充套件方法干擾PageHelper的分頁效果。

  1. Mapper介面中定義自定義查詢方法:

    List<DataPersonVO> customSelectVoList(@Param("wrapper") Wrapper<DataPerson> wrapper);

  2. 在XML中編寫SQL語句:

    <select id="customSelectVoList" resultType="DataPersonVO">
        SELECT * FROM data_person
        <where>
            ${ew.customSqlSegment}
        </where>
    </select>

  3. 呼叫customSelectVoList並結合PageHelper:

    PageHelper.startPage(pageNum, pageSize);
    List<DataPersonVO> oldPersons = mapper.customSelectVoList(wrapper);
    PageInfo<DataPersonVO> pageInfo = new PageInfo<>(oldPersons);

這種方式可以確保分頁效果和分頁資訊正常顯示,但需要手動定義SQL語句。

方案三:使用selectList替代selectVoList

若不需要使用selectVoList方法,可以直接使用MyBatis Plus的selectList方法。selectList方法與PageHelper相容性更高,能正確生成PageInfo分頁資料。

PageHelper.startPage(pageNum, pageSize);
List<DataPersonVO> oldPersons = mapper.selectList(wrapper);
PageInfo<DataPersonVO> pageInfo = new PageInfo<>(oldPersons);

此方法與PageHelper的相容性更高,PageInfo的分頁資訊顯示也更準確。

方案四:手動分頁

在資料量較小的場景下,可以選擇手動分頁,不依賴分頁外掛。具體做法是:

  1. 不使用分頁外掛,直接查詢符合條件的所有資料。

  2. 手動計算分頁偏移量,從結果集中擷取分頁資料。

List<DataPersonVO> oldPersons = mapper.selectVoList(wrapper);
int fromIndex = (pageNum - 1) * pageSize;
int toIndex = Math.min(fromIndex + pageSize, oldPersons.size());
List<DataPersonVO> pagedResult = oldPersons.subList(fromIndex, toIndex);

手動分頁適用於小資料量展示,但不適合大資料量場景。

總結

在MyBatis Plus和PageHelper聯合使用時,使用MyBatis Plus的擴充套件方法(如selectVoList)會導致PageHelper生成的PageInfo資訊不準確。以下為總結的幾種解決方案:

  1. 使用MyBatis Plus自帶分頁外掛:推薦方案,與selectVoList等擴充套件方法相容性更好,能直接返回正確分頁資訊。

  2. 自定義Mapper方法:可透過編寫SQL語句避免MyBatis Plus擴充套件方法,確保PageHelper分頁生效。

  3. 使用selectList替代selectVoList:若數據結構允許,selectList能與PageHelper更好相容。

  4. 手動分頁:適用於小資料量分頁展示,但不適合大資料量。

透過合理選擇適合的方案,可以有效避免分頁資訊不準確的問題,提高程式碼的穩定性和相容性。希望本文能夠幫助大家在專案開發中更好地應用MyBatis Plus與PageHelper,避免類似的分頁問題。

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.