(十一)Mybatis延迟加载(分步查询)的场景及用法详解

这篇文章主要讲述Mybatis延迟加载(分步查询)的场景及用法详解,本篇博客针对于测试方法,及接口等都写了出来,相对来说比较全,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

什么是分步查询?

分步查询就是我把一个多表关联的sql拆成了,多个sql来组合封装到这个对象。也就是一步可以完成的事情,拆成了多步。通过这种形式来减少复杂的sql语句。

什么是延迟加载?

使用延迟加载的前提首先得分步查询,分步查询+延迟加载,在一定情况下可以为我们提升速度,他可以完全避免浪费没有必要的资源。举例:对象当中有子对象,在有时候我只想用他的父对象,如果关联查询,那么就都会查出来,这个时候可以考虑分步延迟查询,用他的子对象的时候查,不用的时候不查。

association-分步查询&延迟加载

这里我们以一对一为例
此处省略了get和set方法等等,主要看重点即可。
Employee类

public class Employee {
	
	private Integer id;
	private String lastName;
	private String email;
	private String gender;
	private Integer dId; //Department关联主键id
	private Department dept;
}

Department 类

public class Department {
	
	private Integer id;
	private String departmentName;

}

开启延迟加载和属性按需加载
在mybatis-config.xml 添加以下配置,即可使用延迟加载

<settings>
	<!--显示的指定每个我们需要更改的配置的值,即使他是默认的。防止版本更新带来的问题  -->
	<setting name="lazyLoadingEnabled" value="true"/>
	<setting name="aggressiveLazyLoading" value="false"/>
</settings>

接口类

package com.atguigu.mybatis.dao;
import java.util.List;
import com.atguigu.mybatis.bean.Employee;

public interface EmployeeMapperPlus {
	
	public Employee getEmpByIdStep(Integer id);

}

xml当中映射文件写法
这里的话主要是association在为我们控制延迟加载。

	<resultMap type="com.gzl.mybatis.bean.Employee" id="MyEmpByStep">
	 	<id column="id" property="id"/>
	 	<result column="last_name" property="lastName"/>
	 	<result column="email" property="email"/>
	 	<result column="gender" property="gender"/>
	 	
	 	<!-- association定义关联对象的封装规则
	 		select:表明当前属性是调用select指定的方法查出的结果,也可以调用别的mapper当中的方法,
	 		直接名称空间.方法id就可调用。
	 		column:指定将哪一列的值传给这个方法
	 		
	 		流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
	 	 -->
	 	 
 		<association property="dept" 
	 		select="getDeptById" column="d_id">
 		</association>
	 </resultMap>
	 
	 <select id="getEmpByIdStep" resultMap="MyEmpByStep">
	 	select * from tbl_employee where id=#{id}
	 </select>
	 
	 <select id="getDeptById" resultType="com.atguigu.mybatis.bean.Department">
		select id,dept_name departmentName from tbl_dept where id=#{id}
	</select>

测试
这时候会发现,我们没有用到dept属性,所以他并没有去执行association里面定义的sql。

在这里插入图片描述

当我们输出dept属性,这个时候mybatis会去执行association里面定义的sql,并赋值给Employee ,也就是在用他的时候,他的查询sql才会执行,然后赋值。

在这里插入图片描述

Collection-分步查询&延迟加载

这里我们以一对多为例
此处省略了get和set方法等等,主要看重点即可。
Department 类

public class Department {
	
	private Integer id;
	private String departmentName;
	private List<Employee> emps;

}

Employee 类

public class Employee {
	
	private Integer id;
	private String lastName;
	private String email;
	private String gender;

}

开启延迟加载和属性按需加载
在mybatis-config.xml 添加以下配置,即可使用延迟加载

<settings>
	<!--显示的指定每个我们需要更改的配置的值,即使他是默认的。防止版本更新带来的问题  -->
	<setting name="lazyLoadingEnabled" value="true"/>
	<setting name="aggressiveLazyLoading" value="false"/>
</settings>

接口类

public interface DepartmentMapper {
	public Department getDeptByIdStep(Integer id);
}

xml
collection 当中的fetchType属性可以控制是否延时加载。
fetchType=eager/lazy可以覆盖全局的延迟加载策略,
指定立即加载(eager)或者延迟加载(lazy)

	<!-- collection:分段查询 -->
	<resultMap type="com.atguigu.mybatis.bean.Department" id="MyDeptStep">
		<id column="id" property="id"/>
		<id column="dept_name" property="departmentName"/>
		<!-- 
			collection定义关联集合类型的属性的封装规则 
			property:指定父类的属性名称
			select:方法名称
			column:把父对象当中的参数传到这个方法当中,也可以传递多个参数
			将多列的值封装map传递;
			column="{key1=column1,key2=column2}"
		-->
		<collection property="emps" 
			select="getEmpsByDeptId"
			column="{deptId=id}" fetchType="lazy">
		</collection>
	</resultMap>
	<!-- public Department getDeptByIdStep(Integer id); -->
	<select id="getDeptByIdStep" resultMap="MyDeptStep">
		select id,dept_name from tbl_dept where id=#{id}
	</select>
	
	<select id="getEmpsByDeptId" resultType="com.atguigu.mybatis.bean.Employee">
		select * from tbl_employee where d_id=#{deptId}
	</select>

测试,当我们不调用他的子对象的时候,会发现他并没有执行那段sql
在这里插入图片描述
当我用到他的子对象的时候,自然回去执行自动封装进去。
在这里插入图片描述

注意

collection可以用来接单个对象嵌套,也可以接对象里面套list
association只可以接单个对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怪 咖@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值