1污桦、Mybatis級聯(lián)分為哪些種類亩歹?如何使用?
2、簡述級聯(lián)使用中的N-1問題和延遲加載
Mybatis級聯(lián)有2種小作,下面是分類及使用:
1亭姥、一對一關(guān)聯(lián)
MyBatis中使用association標(biāo)簽來解決一對一的關(guān)聯(lián)查詢,association標(biāo)簽可用的屬性如下:
property:對象屬性的名稱
javaType:對象屬性的類型
column:所對應(yīng)的外鍵字段名稱
select:使用另一個查詢封裝的結(jié)果
2顾稀、一對多關(guān)聯(lián)
MyBatis中使用collection標(biāo)簽來解決一對多的關(guān)聯(lián)查詢致份,ofType屬性指定集合中元素的對象類型。
級聯(lián)中的N+1問題
N+1問題來源于數(shù)據(jù)庫中常見的級聯(lián)技術(shù)础拨,即N個數(shù)據(jù)庫表形成關(guān)聯(lián)關(guān)系氮块,當(dāng)再增加一個關(guān)聯(lián)表時,也就是N+1個級聯(lián)關(guān)系诡宗,由于某些時候滔蝉,我們并不需要加載數(shù)據(jù)庫的所有數(shù)據(jù),而是某一個數(shù)據(jù)庫表中數(shù)據(jù)塔沃,這時Mybatis會自動加載所有表的數(shù)據(jù)蝠引,多執(zhí)行幾條無關(guān)sql語句,會造成數(shù)據(jù)庫資源的浪費以及系統(tǒng)性能的下降蛀柴,這就是級聯(lián)表的缺點螃概。
Mybatis本身給出解決N+1問題的方案,也就是在N+1個級聯(lián)表的情況下鸽疾,只加載需求的數(shù)據(jù)庫表數(shù)據(jù)吊洼。這是互聯(lián)網(wǎng)發(fā)展的需求,性能提升的途徑制肮。冒窍。
Mybatis 的加載延遲
Mybatis 支持延遲加載,我們希望一次性把常用的級聯(lián)數(shù)據(jù)(針對association 和 collection)通過 SQL 直接查詢出來豺鼻,而對于那些不常用的級聯(lián)數(shù)據(jù)不要取出综液,而是等待要用時才取出,這些不常用的級聯(lián)數(shù)據(jù)可以采用延遲加載的功能儒飒。
在Mybatis 的 settings 配置中配置是否加載延遲:
<setting>
<setting name="lazyLoadingEnabled" value="true">
<setting name="aggressiveLazyLoading" value="false">? #為false啟動按需加載
</setting>
選項 lazyLoadingEnabled 決定是否開啟延遲加載谬莹,
而選項 aggressiveLazyLoading 為 true 的時候,一加載對象(任何一個屬性)就會加載他的全部屬性(如:調(diào)用User對象的任何一個屬性的時候就為這個User對象加載它的 role 屬性)桩了。
為 false 的時候附帽,就是按需加載,調(diào)用User對象 的 role屬性時才會去數(shù)據(jù)庫查詢并加載它的 role 屬性的數(shù)據(jù)圣猎。
此外士葫, Mybatis 中 還有 fetchType 屬性。它存在兩個值送悔。
eager:獲得當(dāng)前POJO 后立即加載對應(yīng)的數(shù)據(jù)慢显。
lazy:獲得當(dāng)前POJO后延遲加載對應(yīng)的數(shù)據(jù)爪模。
如:
<resultMap? id="userRoleResults" type="sqlmapper.User">
<id property="id" column="id" />
<result property="username" column="username" />
<association property="role" column="userRole"? fetchType="eager" select="sqlmapper.RoleMapper.getRoleById"/>
</resultMap>
這樣就會初始化對象的時候就為這個對象加載它的 role 屬性。改成 fetchType=“l(fā)azy” 則調(diào)用User 的 role屬性時才會加載它的 role 屬性的數(shù)據(jù)荚藻。
fetchType 屬性會忽略全局配置項 lazyLoadingEnabled 和 aggressiveLazyLoading 的配置屋灌。