在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
一直是 1
,isLastPage
總是 true
,分頁不生效。進一步分析SQL發現,selectVoList
方法在資料庫查詢時確實被正確加上了LIMIT
分頁引數,因此資料集是正確的,但分頁物件 PageInfo
的 pageNum
等屬性卻不正確。
原因分析
PageHelper在MyBatis攔截層新增分頁引數,以自動修改生成的SQL。但它的分頁上下文資訊捕獲依賴於標準MyBatis查詢,而MyBatis Plus的selectVoList
等擴充套件方法生成SQL的方式有所不同,導致PageHelper在生成PageInfo
時沒有正確捕獲pageNum
等分頁上下文。
具體原因包括:
PageHelper的分頁攔截機制:PageHelper依賴於MyBatis生成的SQL查詢,以自動在SQL中新增分頁引數並生成分頁物件,但某些MyBatis Plus特有方法如
selectVoList
不一定符合這種機制,可能會導致分頁引數未被正確傳遞。PageHelper和MyBatis Plus方法的相容性問題:儘管PageHelper能在查詢中加入分頁引數,但對於MyBatis Plus的擴充套件方法(如
selectVoList
),分頁上下文可能未正確傳遞到PageInfo
中,導致頁面資料不一致。
解決方案
針對以上問題,我們可以考慮以下幾種解決方案:
方案一:使用MyBatis Plus自帶的分頁外掛
MyBatis Plus自帶了分頁外掛,完全支援MyBatis Plus擴充套件方法如selectVoList
,適配性更高,可以確保分頁查詢和分頁資訊的一致性。具體步驟如下:
確保專案中已配置了MyBatis Plus的分頁外掛,例如在Spring Boot專案中引入
PaginationInterceptor
。使用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的分頁外掛可以確保分頁資料準確,包括pageNum
、isLastPage
等分頁資訊正確顯示。
方案二:自定義Mapper方法
如果由於專案限制,無法更換為MyBatis Plus分頁外掛,可以選擇在Mapper中自定義方法,透過編寫SQL語句,避免MyBatis Plus的擴充套件方法干擾PageHelper
的分頁效果。
在
Mapper
介面中定義自定義查詢方法:List<DataPersonVO> customSelectVoList(@Param("wrapper") Wrapper<DataPerson> wrapper);
在XML中編寫SQL語句:
<select id="customSelectVoList" resultType="DataPersonVO"> SELECT * FROM data_person <where> ${ew.customSqlSegment} </where> </select>
呼叫
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
的分頁資訊顯示也更準確。
方案四:手動分頁
在資料量較小的場景下,可以選擇手動分頁,不依賴分頁外掛。具體做法是:
不使用分頁外掛,直接查詢符合條件的所有資料。
手動計算分頁偏移量,從結果集中擷取分頁資料。
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
資訊不準確。以下為總結的幾種解決方案:
使用MyBatis Plus自帶分頁外掛:推薦方案,與
selectVoList
等擴充套件方法相容性更好,能直接返回正確分頁資訊。自定義Mapper方法:可透過編寫SQL語句避免MyBatis Plus擴充套件方法,確保PageHelper分頁生效。
使用selectList替代selectVoList:若數據結構允許,
selectList
能與PageHelper更好相容。手動分頁:適用於小資料量分頁展示,但不適合大資料量。
透過合理選擇適合的方案,可以有效避免分頁資訊不準確的問題,提高程式碼的穩定性和相容性。希望本文能夠幫助大家在專案開發中更好地應用MyBatis Plus與PageHelper,避免類似的分頁問題。