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
文章列表