这篇文章主要讲述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只可以接单个对象