Mybatis中的延迟加载详细解读
作者:夜聆离殇
一. 延迟加载
Mybatis中延迟加载又称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的select查询,延迟加载可以有效的减少数据库的压力。延迟加载仅仅是对关联对象的查询有延迟设置,对于主加载对象都是直接执行查询。
Mybatis根据关联对象查询的select语句的执行时机,分为以下三种:直接加载,侵入式延迟加载,深度延迟加载。
PS:延迟加载的应用要求,关联对象的查询与主加载对象的查询必须是分别进行的select语句,不能是使用多表连接所进行的select查询。因为多表连接查询,本质上是对一个表的查询,对由多个表连接后形成的一张表的查询,会一次性将多个表的所有信息查询出来。
二. 直接加载
执行完主加载对象的查询后,马上执行关联对象的select查询。
1)在mybatis主配置文件中,设置全局属性lazyLoadingEnabled的值为false,那么对于关联对象的查询,都将采用直接加载。即在主加载对象查询后,立即查询关联对象。
<settings>
<!-- 关闭延迟加载 -->
<setting name="lazyLoadingEnabled" value="false"/>
</settings>2)实体类:
public class HeadTeacher {
private Integer id;
private String name;
// private Clazz clazz; //这边不引用,防止关联查询导致死循环
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "HeadTeacher [id=" + id + ", name=" + name + "]";
}
}
public class Clazz {
private Integer id;
private String className;
private Set<HeadTeacher> headTeacher = new LinkedHashSet<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public Set<HeadTeacher> getHeadTeacher() {
return headTeacher;
}
public void setHeadTeacher(Set<HeadTeacher> headTeacher) {
this.headTeacher = headTeacher;
}
@Override
public String toString() {
return "Clazz [id=" + id + ", className=" + className + ", headTeacher=" + headTeacher + "]";
}
}3)映射文件
<mapper namespace="com.mybatisdemo.dao.ClazzDao">
<resultMap type="com.mybatisdemo.beans.Clazz" id="clazzMapper">
<id column="id" property="id"/>
<result column="class_name" property="className"/>
<collection property="headTeacher" ofType="com.mybatisdemo.beans.HeadTeacher"
column="head_teacher_id" select="com.mybatisdemo.dao.HeaderTeacherDao.queryHeadTeacherById"/>
</resultMap>
<select id="queryClazzById" parameterType="int" resultMap="clazzMapper">
select id,class_name,head_teacher_id from clazz where id = #{id}
</select>
</mapper>
<mapper namespace="com.mybatisdemo.dao.HeaderTeacherDao">
<resultMap type="com.mybatisdemo.beans.HeadTeacher" id="headTeacherMapper">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
<select id="queryHeadTeacherById" parameterType="int" resultMap="headTeacherMapper">
select id,name from head_teacher where id = #{id}
</select>
</mapper>4)测试类:
@Test
public void testClazz() {
ClazzDao clazzDao = sqlSession.getMapper(ClazzDao.class);
Clazz clazz = clazzDao.queryClazzById(1);
System.out.println(clazz.getClassName()); //1
System.out.println(clazz.getHeadTeacher().size()); //2
}
我们在1处打断点跟踪,控制台打印如下:

发现我们在进行主加载对象查询时,也对关联对象进行了查询。这就是直接加载。
三. 深度延迟加载
执行对主加载对象的查询时,不会执行对关联对象的查询,访问主加载对象的详情也不会执行对关联对象的查询。只有真正访问关联对象的详情时,才会执行对关联对象的查询。
1)mybatis主配置文件
<settings>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入式延迟加载关闭 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
我们在1处打断点,控制台打印如下:

执行一步到2处,控制台打印如下:

再执行一步,控制台打印:

即:深度延迟加载就是在查询关联对象的详情时,才会执行对关联对象的查询。
四. 侵入式延迟加载
侵入式延迟加载,就是执行对主加载对象的查询时,不会执行对关联对象的查询。但当要访问主加载对象的详情时,就会马上执行关联对象的查询。即对关联对象的查询,侵入到了主加载对象详情查询中。
1)mybatis主配置文件
<settings>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入式延迟加载关闭 -->
<setting name="aggressiveLazyLoading" value="true"/>
</settings>在1处断点,控制台打印如下

执行一步到断点2处,控制台打印如下

发现在查询主加载对象的详情时,已经侵入进行了关联对象的查询。
到此这篇关于Mybatis中的延迟加载详细解读的文章就介绍到这了,更多相关Mybatis延迟加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
