24Mybatis_延遲加載——用association來實現


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

需求:

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

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

 

 

接下來我們用assocation來實現延遲加載:

先給出需求:

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

 

 

老規矩:1.sql語句,2.pojo類,3.mapper.xml和mapper.java接口

第一步:

1。我們要實現延時加載,相當於先查訂單(orders)的信息,等需要用到user的信息時再去查詢User表。

也就是把

  <select id="findOrdersUserLazyLoading" resultMap="OrdersUserLazyLoadingResultMap">
          Select * from orders;
      </select>

 

  <select id="finduserByid" parameterType="int" resultType="cn.itcast.mybatis.po.User">
         SELECT * FROM USER WHERE ID=#{VALUE}
     </select>
     

上面兩條select語句用延遲加載的方式實現。(用resultMap來連接這兩條select語句)

 

 

第二步:

2.pojo類:

package cn.itcast.mybatis.po;

import java.util.Date;
import java.util.List;

public class Orders {
private Integer id;
private Integer user_id;
private String number;
private Date createtime;
private String note;
//用戶信息,新增了一個User屬性,為了保存查詢得到的關聯的User表的信息(一對一)
private User user;



public List<Orderdetail> getOrderdetail() {
    return orderdetails;
}
public void setOrderdetail(List<Orderdetail> orderdetail) {
    this.orderdetails = orderdetail;
}
public User getUser() {
    return user;
}
public void setUser(User user) {
    this.user = user;
}
public Integer getId() {
    return id;
}
public void setId(Integer id) {
    this.id = id;
}
public Integer getUser_id() {
    return user_id;
}
public void setUser_id(Integer user_id) {
    this.user_id = user_id;
}
public String getNumber() {
    return number;
}
public void setNumber(String number) {
    this.number = number;
}
public Date getCreatetime() {
    return createtime;
}
public void setCreatetime(Date createtime) {
    this.createtime = createtime;
}
public String getNote() {
    return note;
}
public void setNote(String note) {
    this.note = note;
}


}

 

第三步:

3.編寫OrderMapperCustom.xml代碼:使用association中的select指定延遲加載去執行的statement的id。

 <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserLazyLoadingResultMap">這句代碼的作用就是用來連接上面那兩條select語句來實現延遲加載。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- nanmespace:命名空間。 作用就是對sql進行分類話管理,理解Sal分離

注意:使用mapper代理方式,namespace有特殊重要的作用
-->

<mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom">
  

     <!-- 延遲加載的resultMap -->
    <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserLazyLoadingResultMap">
            <!--對訂單信息進行映射配置  -->
     
     <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserLazyLoadingResultMap">
         <id column="id" property="id"/>
         <result column="user_id" property="user_id"/>
         <result column="number" property="number"/>
         <result column="createtime" property="createtime"/>
         <result column="note" property="note"/>
         
         <!-- 實現對用戶信息進行延遲加載
            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="cn.itcast.mybatis.po.User" 
             select="finduserByid" column="user_id"
             >
         </association>
     </resultMap>
     
     
     <select id="finduserByid" parameterType="int" resultType="cn.itcast.mybatis.po.User">
         SELECT * FROM USER WHERE ID=#{VALUE}
     </select>
     

     
      
      <select id="findOrdersUserLazyLoading" resultMap="OrdersUserLazyLoadingResultMap">
          Select * from orders;
      </select>
      
      
</mapper>

編寫OrdersMapperCustom.java接口:

package cn.itcast.mybatis.mapper;

import java.util.List;

import cn.itcast.mybatis.po.Orders;
import cn.itcast.mybatis.po.OrdersCustom;
import cn.itcast.mybatis.po.User;

public interface OrdersMapperCustom {
    //函數的名字OrdersMapperCustom.xml中select中的id名一樣
    
     public List<Orders> findOrdersUserLazyLoading();
}

 

第四步:

不要忘記修改總的配置文件,setting 加上延遲加載的功能

           延遲加載配置

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

 

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

lazyLoadingEnabled、aggressiveLazyLoading

設置項

描述

允許值

默認值

lazyLoadingEnabled

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

true | false

false

aggressiveLazyLoading

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

true | false

true

 

 

在SqlMapConfig.xml中代碼為:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    
      
    
    <!-- properties的配置必須寫在typeAliases的上面 -->
    <properties resource="db.properties"></properties>

<!-- 配置懶加載設置 -->
<settings> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings> <!-- 和spring整合后 environments配置將廢除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事務管理--> <transactionManager type="JDBC" /> <!-- 數據庫連接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments> <!-- 把映射文件(sqlmap/user.xml)加載進sqlMapConfig.xml--> <mappers> <!-- 把mapper.xml加載進sqlMapConfig.xml--> <!-- 遵循一些規范:需要將mapper接口類名和mapper.xml映射文件名稱保持一致 且在一個目錄中。 當着這個規范的前提是:使用mapper代理方法。 --> <mapper class="cn.itcast.mybatis.mapper.OrdersMapperCustom"/> </mappers> </configuration>

 

第五步:

編寫測試代碼:

            測試思路:

1、執行上邊mapper方法(findOrdersUserLazyLoading),內部去調用cn.itcast.mybatis.mapper.OrdersMapperCustom中的findOrdersUserLazyLoading只查詢orders信息(單表)。

 

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

 

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

 

 測試代碼Mybatis_mappertest.java如下:

package cn.itcast.mybatis.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import cn.itcast.mybatis.mapper.OrdersMapperCustom;
import cn.itcast.mybatis.mapper.userMapper;
import cn.itcast.mybatis.po.Orders;
import cn.itcast.mybatis.po.User;
import cn.itcast.mybatis.po.UserCustom;
import cn.itcast.mybatis.po.UserQueryVo;

public class Mybatis_mappertest {
    
    private SqlSessionFactory sqlSessionFactory;
    @Before
    public void setup() throws IOException
    {   String resource="SqlMapConfig.xml";
        InputStream inputStream= Resources.getResourceAsStream(resource);
        //主要是生成SqlsessionFactory。
        this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testMaper()
    {
        SqlSession sqlSession=null;
        
        sqlSession=sqlSessionFactory.openSession();
        //生成代理類
        OrdersMapperCustom orderMapper=sqlSession.getMapper(OrdersMapperCustom.class);
    //創建包裝對象,設置查詢條件
        //orderMapper.findOrdersUser();
        
       @SuppressWarnings("unused")
    
    
    List<Orders> list=orderMapper.findOrdersUserLazyLoading();
       for(Orders orders:list)
           
       {//只有執行了這一步才會執行延遲加載。
           User user=orders.getUser();
           System.out.println(user);
           
           
       }
    
    
    }

}

運行結果如下:

DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@30647e13]
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
cn.itcast.mybatis.po.User@1ff90029

  我們看一下上面的結果:第一條sql語句:Select * from orders;

 

 

    然后才會有:SELECT * FROM USER WHERE ID=?

 

 

實現了延遲加載、

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM