Mybatis N+1問題解析
因為熱愛,所以拼搏。 —RuiDer
前導必備
- Mybatis
- 資料庫
- 級聯
N+1問題??
N+1問題來源於資料庫中常見的級聯技術,即N個資料庫表形成關聯關係,當再增加一個關聯表時,也就是N+1個級聯關係,由於某些時候,我們並不需要載入資料庫的所有資料,而是某一個資料庫表中資料,這時Mybatis會自動載入所有表的資料,多執行幾條無關sql語句,會造成資料庫資源的浪費以及系統效能的下降,這就是級聯表的缺點。
如何解決N+1問題
Mybatis本身給出解決方案,就是延遲載入。
延遲載入
延遲載入會解決上述的N+1問題,也就是在N+1個級聯表的情況下,只載入需求的資料庫表資料。這是網際網路發展的需求,效能提升的途徑。
如何配置Mybatis完成延遲載入
全域性配置:
- lazyLoadingEnabled true/false
- aggressiveLazyLoading true/false
lazyLoadingEnabled:延遲載入的全域性開關,當開啟時,所有關聯都會延遲載入。在特定的關聯中,
使用fetchType屬性覆蓋該內容的功能。fetchType將在後面介紹。
aggressiveLazyLoading:是層級延遲載入開關,什麼意思呢?就是處於同一個層級的關聯表會同
時延遲載入,或者同時被載入。
配置:
在Mybatis的全域性配置中的setting標籤中加入設定
<setting>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="true"/>
</setting>
全域性配置的缺點
上面的配置屬於全域性配置,會出現一個問題,同一個層級的級聯表也存在需求性的差異,同一級的某個資料庫表的資料或許不是我們經常使用的,那麼上述的配置也會影響系統的效能。
全域性配置的優化 — fetchType屬性
Mybatis使用fetchType屬性解決全域性配置的缺點。fetchType出現在級聯元素association,collection中,它存在兩個值
- eager:獲得當前POJO後立即載入對應的資料。
- lazy:獲得當前POJO後延遲載入對應的資料。
配置:
<collection properties=".." column=".." fetchType="eager"
select="對映介面"
/>