Mybatis collection標籤配合PageHapler分頁問題
阿新 • • 發佈:2021-10-28
一、問題現象
在mybatis的resultMap標籤中使用collection或者assocation做巢狀結果對映,再配合PageHalper實現分頁效果的時候,會出現兩個問題:
實際查出來的資料,會部分丟失,比如傳的頁面大小是10條,那麼有可能會返回小於10條記錄。 分頁物件的total總數與實際返回的數量不一致。
二、問題原因
在定位問題前,我們先了解下PageHalper的工作原理,PageHapler主要是通過攔截器實現的,在執行sql前會根據頁碼和頁數在sql的後面加上關鍵字,比如limit,rownum等。
在PageHapler攔截SQL新增分頁關鍵字成功後,由於巢狀結果集的方式會導致結果集被摺疊,因此分頁查詢後的結果在摺疊後總數會減少,所以無法保證分頁結果數量正確。
在PageHapler官網的常見問題列表中也有對此問題的說明:
為什麼不支援一對一和一對多結果對映的分頁查詢?
在一對一和一對多時,根據分頁條件查詢出 100 條資料時,由於一對一和一對多會去重,經過巢狀處理後資料量會減少,因此分頁想要獲得 100 條資料無法實現。想要支援這種情況可以使用巢狀查詢。巢狀查詢是要額外執行SQL,主SQL可以得到正確的結果數量,因此可以正常分頁。
三、解決方法
使用mybatis的巢狀查詢,在resultMap的collection標籤中使用select屬性額外執行SQL,如果資料量比較大的時候,可能對效能影響嚴重。
<resultMapid="list"type
<idcolumn="id_"property="id"/>
<resultcolumn="name_"property="name"/>
<collectionproperty="users"
javaType="java.util.ArrayList"
ofType="com.xxx.xxx.xxx.xxx"
select="com.xxx.xxx.xxx.xxx.xxxx"
column="{id=id_}"/>
</resultMap>在業務層service中,拿到主SQL的結果集,再傳入條件去執行額外SQL獲取結果集。