什么是延迟加载?
所谓延迟加载就是先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
延迟加载的分类
直接加载: 执行完主加载立刻执行对关联对象的加载
侵入式延迟:执行一条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(); }
结果
延迟加载策略总结
本次分享就到这 谢谢观看!