九.延迟加载

什么是延迟加载?

  所谓延迟加载就是先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

 

延迟加载的分类

  直接加载: 执行完主加载立刻执行对关联对象的加载    

  侵入式延迟:执行一条SQL语句返回一个对象,如果访问这个对象的属性,则会走第二条SQL语句,否则反之

  深度延迟:执行一条SQL语句返回一个对象,如果访问这个对象的属性,并且访问关联对象的属性,则会走第二条SQL,否则反之

 

实体类

 

package cn.happy.entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2018/2/26.
 */
//所属部门类
public class Dept implements Serializable{
    public Integer deptNo;
    public String deptName;
    public List<Emp> emps=new ArrayList<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 List<Emp> getEmps() {
        return emps;
    }

    public void setEmps(List<Emp> emps) {
        this.emps = emps;
    }
}

 

  

package cn.happy.entity;

import java.io.Serializable;

/**
 * Created by Administrator on 2018/2/26.
 */
//员工类
public class Emp implements Serializable{
    public Integer empNo;
    public String empName;
    public Integer deptNo;
    public Dept dept;

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    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;
    }

    public Integer getDeptNo() {
        return deptNo;
    }

    public void setDeptNo(Integer deptNo) {
        this.deptNo = deptNo;
    }
}

  

创建接口方法

//一对多多条SQL
    public Dept getDeptByIdMultSQL(int id);

  注意: 使用延迟加载和深度加载时必须把延迟加载开启,在大配置文件中配置如下。实现延迟加载必须使用多条SQL才行,因为使用单条就会直接加载!!!

  

 <setting name="lazyLoadingEnabled" value="true"/>    <!--延迟加载是否开启   默认false-->

  

 

xml文件配置

<!--多条SQL-->
    <resultMap id="empMapper" type="Dept">
        <result column="deptName" property="deptName"></result>
        <collection property="emps" ofType="Emp" select="selectMultSQL" column="deptNo">
        </collection>
    </resultMap>
    <select id="getDeptByIdMultSQL" resultMap="empMapper">
        SELECT * from dept
        where deptNo=#{deptNo} 
  </select>
<select id="selectMultSQL" resultType="Emp">
SELECT * from emp where deptNo=#{deptNo}
</select>

  

 

直接加载

  MyBatis默认开启 ,如果在大配置文件中没有设置延迟加载就会直接执行两条SQL

实体类实现代码

//3.直接加载
    @org.junit.Test
    public void t1LazyLodingEanbled(){
        SqlSession sqlsession= MyBatisUtil.getOpenSession();
        IDeptDao mapper = sqlsession.getMapper(IDeptDao.class);
        Dept deptById = mapper.getDeptByIdMultSQL(1);
        System.out.println(deptById.getDeptName());
        sqlsession.close();

    }

  结果

 

侵入式延迟

  使用侵入式延迟需要在大配置文件中配置以下节点

  

<!--侵入式延迟-->
        <setting name="lazyLoadingEnabled" value="true"/>    <!--延迟加载是否开启   默认false-->
        <setting name="aggressiveLazyLoading" value="true"/> <!--侵入式延迟是否开启  默认true-->

  测试

   

 //4.侵入式延迟
    @org.junit.Test
    public void t2LazyLodingEanbled(){
        SqlSession sqlsession= MyBatisUtil.getOpenSession();
        IDeptDao mapper = sqlsession.getMapper(IDeptDao.class);
        Dept deptById = mapper.getDeptByIdMultSQL(1);
        System.out.println("---------分割线-------------");
     //调用该对象的属性 System.out.println(deptById.getDeptName()); sqlsession.close(); }

  结果

 

分析:在返回结果对象前查询了一条SQL,然后在调用该对象的属性时又查询了一条SQL

 

深度延迟

  修改大配置文件

  

<!--深度延迟-->

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

  测试

  

 //4.深度延迟
    @org.junit.Test
    public void t3LazyLodingEanbled(){
        SqlSession sqlsession= MyBatisUtil.getOpenSession();
        IDeptDao mapper = sqlsession.getMapper(IDeptDao.class);
        Dept deptById = mapper.getDeptByIdMultSQL(1);
        System.out.println("---------分割线-------------");
        //调用该对象的关联对象的属性
        for (Emp emp:deptById.getEmps()) {
            System.out.println( emp.getDeptNo());
        }
        sqlsession.close();

    }

  结果

 

 

延迟加载策略总结

 

本次分享就到这 谢谢观看!

 

posted @ 2018-02-28 14:29  徐昌琦  阅读(165)  评论(0编辑  收藏  举报