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