文章出處

1.什么是延遲加載

resultMap可以實現高級映射(使用association、collection實現一對一及一對多映射),association、collection具備延遲加載功能。

需求:

如果查詢訂單并且關聯查詢用戶信息。如果先查詢訂單信息即可滿足要求,當我們需要查詢用戶信息時再查下用戶信息。把對用戶信息的按需去查詢就是延遲加載。

延遲加載:先從單表查詢、需要時再從關聯表去關聯查詢,大大提高數據庫性能,因為查詢單表要比關聯查詢多張表速度要快。

2.使用association實現延遲加載

2.1需求

查詢訂單并且關聯查詢用戶信息

2.2mapper.xml

需要定義兩個mapper的方法對應的statement。

(1)只查詢訂單信息

SELECT * FROM orders

在查詢訂單的statement中使用association去延遲加載(執行)下邊的statement(關聯查詢用戶信息)。

  <!-- 查詢訂單關聯查詢用戶  -->
    <select id="findOrdersUserLazyLoading" resultMap="OrdersUserLazyLoadingResultMap">
        SELECT * FROM orders
    </select>

(2)關聯查詢用戶信息

通過上邊查詢到的訂單信息中user_id去關聯查詢用戶信息

使用UserMapper.xml中的findUserById

   <select id="findUserById" parameterType="int" resultType="user">
        select * from user where id=#{value}
    </select>

上邊先去執行findOrdersUserLazyLoading,當需要去查詢用戶的時候再去執行fingUserById,通過resultMap的定義將延遲加載執行配置起來。

2.3 延遲加載resultMap

使用association中的select指定延遲加載去執行的statement的id。

<!-- 延遲加載的resultMap  -->
    <resultMap type="joanna.yan.mybatis.entity.Orders" id="OrdersUserLazyLoadingResultMap">
        <!-- 1.對訂單信息進行映射配置 -->
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
        <!-- 2.實現對用戶信息進行延遲加載 -->
        <!-- select:指定延遲加載需要執行的statement的id(是根據user_id查詢用戶信息的statement) 
               要使用UserMapper.xml中findUserById完成根據用戶id(user_id)用戶信息的查詢,
               如果findUserById不在本mapper中需要前邊加namespace。
             column:訂單信息中關聯用戶信息查詢的列,是user_id
              關聯查詢的sql理解為:
             SELECT orders.*,
                (SELECT username FROM USER WHERE orders.user_id = user.id)username,
                (SELECT sex FROM USER WHERE orders.user_id = user.id)sex
             FROM orders
        -->
        <association property="user" javaType="joanna.yan.mybatis.entity.User"
            select="joanna.yan.mybatis.mapper.UserMapper.findUserById" column="user_id">
        </association>
    </resultMap>

2.4mapper.java

    //查詢訂單關聯查詢用戶,用戶信息時延遲加載
    public List<Orders> findOrdersUserLazyLoading() throws Exception;

2.5測試

2.5.1測試思路

(1)執行上邊mapper方法(findOrdersUserLazyLoading),內部去調用joanna.yan.mybatis.mapper.OrdersCustomMapper中findOrdersUserLazyLoading只查詢orders信息(單表)。

(2)在程序中去遍歷上一步驟查詢出的List<Orders>,當我們調用Orders中的getUser()時,開始進行延遲加載。

(3)延遲加載,去調用UserMapper.xml中findUserById這個方法獲取用戶信息。

2.5.2延遲加載配置

mybatis默認沒有開啟延遲加載,需要在SqlMapConfig.xml中setting配置。

在mybatis核心配置文件中配置:

lazyLoadingEnabled、aggressiveLazyLoading

設置項

描述

允許值

默認值

lazyLoadingEnabled

全局性設置懶加載。如果設為‘false’,則所有相關聯的都會被初始化加載。

true | false

false

aggressiveLazyLoading

當設置為‘true’的時候,懶加載的對象可能被任何懶屬性全部加載。否則,每個屬性都按需加載。

true | false

true

在SqlMapConfig.xml中配置:

  <!-- 全局配置參數,需要時再設置  -->
     <settings>
         <!-- 打開延遲加載的開關  -->
         <setting name="lazyLoadingEnabled" value="true"/>
         <!-- 將積極加載改為消極加載即按需要加載 -->
         <setting name="aggressiveLazyLoading" value="false"/>
     </settings>

2.5.3測試代碼

    @Test
    public void findOrdersUserLazyLoadingTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        OrdersCustomMapper ordersCustomMapper=sqlSession.getMapper(OrdersCustomMapper.class);
        List<Orders> list=ordersCustomMapper.findOrdersUserLazyLoading();
        for (Orders orders : list) {
            //執行getUser()去查詢用戶信息,這里實現按需加載
            User user=orders.getUser();
            System.out.println(user);
        }
        sqlSession.close();
    }

2.6延遲加載思考

不使用mybatis提供的association及collection中的延遲加載功能,如何實現延遲加載?

實現方法如下:

定義兩個mapper方法:

(1)查詢訂單列表

(2)根據用戶id查詢用戶信息

    實現思路:先去查詢第一個mapper方法,獲取訂單信息列表

       在測試程序中,按需去調用第二個mapper方法去查詢用戶信息。

總之,使用延遲加載方法,先去查詢簡單的sql(最好單表,也可以關聯查詢),再去按需要加載關聯查詢的其它信息。

 

轉載自http://www.cnblogs.com/Joanna-Yan/p/6953005.html


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()