Mybatis N+1問題解析

馬和德發表於2019-01-19

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="對映介面"
        />

我的github
我的部落格
CSDN

相關文章