【MyBatis框架】高級映射-延遲加載

延遲加載
1.什麼是延遲加載

resultMap能夠實現高級映射(使用association、collection實現一對一及一對多映射),association、collection具有延遲加載功能。
需求:
若是查詢訂單而且關聯查詢用戶信息。若是先查詢訂單信息便可知足要求,當咱們須要查詢用戶信息時再查詢用戶信息。把對用戶信息的按需去查詢就是延遲加載。

延遲加載:先從單表查詢、須要時再從關聯表去關聯查詢,大大提升數據庫性能,由於查詢單表要比關聯查詢多張錶速度要快。

2.使用association實現延遲加載

2.1需求
查詢訂單而且關聯查詢用戶信息

2.2mapper.xml

須要定義兩個mapper的方法對應的statement。
(1)只查詢訂單信息
SELECT * FROM ordersjava

<!-- 查詢訂單,關聯查詢用戶,用戶信息須要延遲加載 -->
     <select id="findOrdersUserLazyLoading" resultMap="OrdersUserLazyLoadingResultMap">
         SELECT * FROM orders
     </select>

在查詢訂單的statement中使用association去延遲加載(執行)下邊的satatement(關聯查詢用戶信息)
 
(2)關聯查詢用戶信息
經過上邊查詢到的訂單信息中user_id去關聯查詢用戶信息
mysql

<!-- 延遲加載使用的sql -->
     <select id="findUserById" parameterType="int" resultType="cn.edu.hpu.mybatis.PO.User">
      SELECT * FROM USER WHERE id=#{id}
    </select>

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

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

    <!-- 延遲加載的resultMap -->
     <resultMap id="OrdersUserLazyLoadingResultMap" type="cn.edu.hpu.mybatis.PO.Orders">
         <!-- 對訂單信息進行映射配置 -->
             <id column="id" property="id"/>
            <result column="user_id" property="userId"/>
            <result column="number" property="number"/>
            <result column="creattime" property="creattime"/>
            <result column="note" property="note"/>
         
         <!-- 實現延遲加載用戶信息 
         select:指定延遲加載所須要執行的sql語句,也就是Mapper.xml配置文件中的某個SELECT標籤對
         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="cn.edu.hpu.mybatis.PO.User" select="findUserById" column="user_id">
             
         </association>
 
     </resultMap>

2.4mapper.java數據庫

package cn.edu.hpu.mybatis.mapper;

import java.util.List;

import cn.edu.hpu.mybatis.PO.Orders;
import cn.edu.hpu.mybatis.PO.OrdersCustom;
import cn.edu.hpu.mybatis.PO.User;

//訂單mapper
public interface OrdersCustomMapper {


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

2.5測試
2.5.1測試思路:
一、執行上邊mapper方法(findOrdersUserLazyLoading),內部去調用 cn.itcast.mybatis.mapper.OrdersMapperCustom中的findOrdersUserLazyLoading只查 詢orders信息(單表)。

二、在程序中去遍歷上一步驟查詢出的List<Orders>,當咱們調用Orders中的getUser方法時,開始進行延遲加載。

三、延遲加載,去調用UserMapper.xml中findUserbyId這個方法獲取用戶信息。

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

在mybatis核心配置文件中配置:
lazyLoadingEnabled、aggressiveLazyLoading
設置項 描述 容許值 默認值
lazyLoadingEnabled 全局性設置懶加載。若是設爲‘false’,則全部相關聯的都會被初始化加載。true | falsefalse
aggressiveLazyLoading 當設置爲‘true’的時候,懶加載的對象可能被任何懶屬性所有加載。不然,每一個屬性都按需加載。true | falsetrue

在SqlMapConfig.xml中配置:mybatis

<configuration>
    
    ......
    
    <!-- settings-->
    <settings>
        <!-- 打開延遲加載的開關 -->
        <setting name="lazyLoadingEnable" value="true"/>
        <!-- 將積極加載改成消極加載(及按需加載) -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>


    ......
</configuration>

2.5.3測試代碼
//查詢訂單關聯用戶信息,用戶信息實現延遲加載
app

@Test
    public void testFindOrderUserLazyLoading() throws Exception{
        
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //建立代理對象
        OrdersCustomMapper ordersMapperCustom=sqlSession.getMapper(OrdersCustomMapper.class);
        
        //調用mapper的方法
        List<Orders> ods=ordersMapperCustom.findOrdersUserLazyLoading();
        
        for (int i = 0; i < ods.size(); i++) {
            Orders od=ods.get(i);
            //執行getUser去查詢用戶信息,這裏實現了延遲加載
            User user=od.getUser();
            System.out.println("用戶姓名:"+user.getUsername());
        }
    }

輸出結果及日誌信息:性能

DEBUG [main] - Opening JDBC Connection  
DEBUG [main] - Created connection 29706134.  
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@1c54796]  
DEBUG [main] - ==>  Preparing: SELECT * FROM orders   
DEBUG [main] - ==> Parameters:   
DEBUG [main] - <==      Total: 3  
DEBUG [main] - ==>  Preparing: SELECT * FROM USER WHERE id=?   
DEBUG [main] - ==> Parameters: 1(Integer)  
DEBUG [main] - <==      Total: 1  
用戶姓名:張三  
用戶姓名:張三  
DEBUG [main] - ==>  Preparing: SELECT * FROM USER WHERE id=?   
DEBUG [main] - ==> Parameters: 3(Integer)  
DEBUG [main] - <==      Total: 1  
用戶姓名:劉莉莉

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

實現方法以下:
定義兩個mapper方法:
一、查詢訂單列表
二、根據用戶id查詢用戶信息
實現思路:
先去查詢第一個mapper方法,獲取訂單信息列表
在程序中(service),按需去調用第二個mapper方法去查詢用戶信息。

總之:
測試

使用延遲加載方法,先去查詢簡單的sql(最好單表,也能夠關聯查詢),再去按須要加載關聯查詢的其它信息。spa

相關文章
相關標籤/搜索