MyBatis(十):MyBatis懶加載 延遲加載詳解

  1. 延遲加載介紹java

    ​ MyBatis中的延遲加載,也成爲懶加載,是指在進行關聯查詢時,按照設置的延遲規則推遲對關聯對象的查詢。延遲加載能夠有效的減小數據庫的壓力。延遲加載只是針對有延遲設置的關聯對象的推遲查詢,對於主主查詢是直接進行執行SQL語句。數據庫

  2. MyBatis關聯查詢加載時機app

    • 直接加載:執行完主對象的查詢後,立刻執行對關聯對象的查詢語句
    • 侵入式延遲:執行完對主對象對查詢後,不會執行對關聯對象的查詢,但當訪問主對象的屬性詳情是,就會執行關聯對象的查詢
    • 深度延遲:只有當真正訪問關聯對象的詳情時,纔會執行查詢語句
  3. MyBatis延遲加載實現步驟測試

    • 全局延遲fetch

      在MyBatis核心配置類中添加標籤ui

      <settings>
              <!-- 延遲加載總開關 -->
              <setting name="lazyLoadingEnabled" value="true"/>
              <!-- 侵入式延遲加載開關 -->
              <setting name="aggressiveLazyLoading" value="true"/>
      </settings>
    • 部分延遲線程

      在關聯查詢collectionassociation標籤上添加 fetchType 屬性,lazy表示延遲加載,eager表示當即加載,指定屬性後,將在映射中忽略全局配置參數 lazyLoadingEnabled,使用屬性的debug

      <resultMap id="userMap" type="com.rangers.entity.User">
          <result column="id" property="id"></result>
          <result column="name" property="name"></result>
          <result column="address" property="address"></result>
      
          <collection property="orderList" column="id" ofType="com.rangers.entity.Order"
                      select="com.rangers.dao.OrderMapper.findOrderById" fetchType="lazy">
          </collection>
      </resultMap>
      
      <select id="findUserById" resultMap="userMap">
          select * from user where id=#{id}
      </select>
      <select id="findOrderById" parameterType="int" resultType="com.rangers.entity.Order">
          select * from `order` where uid=#{id}
      </select>
  4. 注意點code

    在延遲加載的測試過程當中,有發現延遲加載未生效問題,就是在用戶表查詢後,訂單信息也有值。xml

    ​ 通過探索發現,在debug模式下查看變量時,debug會另起一個線程,而後從新調用代碼,debug彈出框顯示用戶信息時,會自動調用User類的hashCode()toString()方法。

    解決一:不進行debug打斷電,在查詢後直接打印一段分割線,查看控制檯信息

    @org.junit.Test
    public void testResult(){
        User user = userMapper.findUserById(1);
        System.out.println("------------------查詢OrderList分割線------------------");
        System.out.println(user.getOrderList());
    }

    控制檯顯示

    17:33:31,229 DEBUG findUserById:159 - ==>  Preparing: select * from user where id=? 
    17:33:31,253 DEBUG findUserById:159 - ==> Parameters: 1(Integer)
    17:33:31,283 DEBUG findUserById:159 - <==      Total: 1
    ------------------查詢OrderList分割線------------------
    17:33:31,284 DEBUG findOrderById:159 - ==>  Preparing: select * from `order` where uid=? 
    17:33:31,284 DEBUG findOrderById:159 - ==> Parameters: 1(Integer)
    17:33:31,290 DEBUG findOrderById:159 - <==      Total: 2
    [Order{id=1, time=Wed Mar 10 17:22:30 CST 2021, total=1.11, uid=1, flag=0}, Order{id=2, time=Wed Mar 10 17:22:45 CST 2021, total=2.22, uid=1, flag=1}]

    解決二:在MyBatis核心配置文件中添加setting標籤,指定lazyLoadTriggerMethods屬性爲空

    <setting name="lazyLoadTriggerMethods" value=""/>

    lazyLoadTriggerMethods:指定對象的方法觸發一次延遲加載。

    默認值:equals() clone() hashCode() ) toString()

相關文章
相關標籤/搜索