mybatis中的延遲加載


一、延遲加載

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

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

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

     lazyLoadingEnabled、aggressiveLazyLoading

設置項

描述

允許值

默認值

lazyLoadingEnabled

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

true | false

false

aggressiveLazyLoading

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

true | false

true

<settings>

      <setting name="lazyLoadingEnabled" value="true"/>

      <setting name="aggressiveLazyLoading" value="false"/>

</settings>

場合:

         當只有部分記錄需要關聯查詢其它信息時,此時可按需延遲加載,需要關聯查詢時再向數據庫發出sql,以提高數據庫性能。

         當全部需要關聯查詢信息時,此時不用延遲加載,直接將關聯查詢信息全部返回即可,可使用resultType或resultMap完成映射。

二:案例:(在部門和員工一對多)

源碼介紹:

1.Dept.java

package cn.zhang.entity;

import java.util.HashSet;
import java.util.Set;

public class Dept {
    
    private Integer deptno;

    private String deptname;

    private Set<Emp> emp = new HashSet<Emp>();
    

    @Override
    public String toString() {
        return "Dept [deptno=" + deptno + ", deptname=" + deptname + ", emp="
                + emp + "]";
    }

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    public String getDeptname() {
        return deptname;
    }

    public void setDeptname(String deptname) {
        this.deptname = deptname;
    }

    public Set<Emp> getEmp() {
        return emp;
    }

    public void setEmp(Set<Emp> emp) {
        this.emp = emp;
    }

}
View Code

2.Emp.java

package cn.zhang.entity;

public class Emp {
    
    private Integer empno;
    
    private String empname;
    

    @Override
    public String toString() {
        return "Emp [empno=" + empno + ", empname=" + empname + "]";
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }


    

}
View Code

3.MybatisUtil.java

package cn.zhang.util;

import java.io.IOException;
import java.io.Reader;

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

/**
 * 工具類
 * 
 */
public class MybatisUtil {

    private static String config = "mybatis-config.xml";
    static Reader reader;
    static {
        try {
            reader = Resources.getResourceAsReader(config);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static SqlSessionFactory factory = new SqlSessionFactoryBuilder()
            .build(reader);

    // 提供一個可以獲取到session的方法
    public static SqlSession getSession() throws IOException {

        SqlSession session = factory.openSession();
        return session;
    }
}
View Code

4.DeptDao.java

package cn.zhang.dao;

import java.io.IOException;
import cn.zhang.entity.Dept;

public interface DeptDao {

    /**
     * 查詢指定記錄
     * @return
     * @throws IOException
     */
    public Dept findById(Integer id) throws IOException;


}
View Code

5.DeptDAO.xml

<?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">
<mapper namespace="cn.zhang.dao.DeptDao">
    <!-- 3.根據員工id查詢員工信息 -->
    <select id="selectEmpByDeptNo" resultType="Emp">
        select empno,empname
        from emp where deptno=#{deptno}
    </select>
    <!-- 2.對部門實體的映射 -->
    <resultMap type="Dept" id="deptMapper">
        <id property="deptno" column="deptno" />
        <result property="deptname" column="deptname" />
        <!-- 一對多部門關聯的員工 -->
        <!--select:關聯員工查詢 -->
        <!--column:關聯員工查詢所需要的條件(來源於1) -->
        <collection property="emp" ofType="Emp" select="selectEmpByDeptNo"
            column="deptno" />
    </resultMap>
    <!--1.根據部門id查詢部門信息 -->
    <select id="findById" resultMap="deptMapper">
        select deptno,deptname from dept
        where deptno=#{deptno}
    </select>

</mapper>
View Code

6.mybatis-config.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>
    <!--lazyLoadingEnabled:設置懶加載,默認為false。如果為false:則所有相關聯的都會被初始化加載。
     aggressiveLazyLoading:默認為true。當設置為true時,懶加載的對象可能被任何懶屬性全部加載;否則,每個屬性按需加載。 -->
    <settings>
        <!-- 打開延遲加載的開關 -->
        <setting name="lazyLoadingEnabled" value="true" />
        <!-- 將積極加載改為消息加載即按需加載 -->
        <setting name="aggressiveLazyLoading" value="false" />
    </settings>
    <!-- 配置別名 -->
    <typeAliases>
        <!--方式一: 按類型名定制別名 -->
        <!--方式二: 拿當前指定包下的簡單類名作為別名 -->
        <package name="cn.zhang.entity" />
    </typeAliases>
    <environments default="oracle">

        <environment id="oracle">
            <!-- 使用jdbc的事務 -->
            <transactionManager type="JDBC" />
            <!-- 使用自帶的連接池 -->
            <dataSource type="POOLED">
                <!-- 我用的Oracle數據庫 -->
                <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
                <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
                <property name="username" value="study" />
                <property name="password" value="123" />
            </dataSource>
        </environment>

    </environments>
    <mappers>
        <mapper resource="cn/zhang/dao/DeptDAO.xml" />
    </mappers>
</configuration>
View Code

7.MyTest.java(測試類)

package cn.zhang.test;
//一對多
import java.io.IOException;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;
import cn.zhang.dao.DeptDao;
import cn.zhang.entity.Dept;
import cn.zhang.util.MybatisUtil;

public class MyTest {
    
    DeptDao dao;
    @Before
    public void initData() throws IOException{
        SqlSession session = MybatisUtil.getSession();
        dao = session.getMapper(DeptDao.class);
    }
    
    
    /**
     * 查詢指定記錄
     * @throws IOException
     */
    @Test
    public void findAll() throws IOException{
        
        Dept dept = dao.findById(1);
        System.out.println(dept);
        
    }
}
View Code

測試結果:

在下面位置打斷點

情況一:在mybatis-config.xml中不做配置情況

情況二:在mybatis-config.xml中配置

<settings>
    <!-- 打開延遲加載的開關 -->
    <setting name="lazyLoadingEnabled" value="true" />
    <!-- 將積極加載改為消息加載即按需加載 -->
    <setting name="aggressiveLazyLoading" value="false" />
</settings>

下一步:

F6下步:

F6下步:打出員工的名字

 情況三:

F6下一步:

 

 F6下一步:打印出員工名字

 


免責聲明!

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



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