关联查询_association分步查询
在上一篇文章文章中MyBatis学习–映射文件_select_resultMap_关联查询_环境搭建以及级联属性封装结果以及association定义关联对象封装规则,介绍了级联查询结果封装,这篇文章主要讲述如何实现分步查询。
使用场景:
1. 先按照员工id查询员工信息;
2. 根据查询员工信息中的d_id值去部门表查出部门信息;
3. 将部门信息设置到员工信息中。
使用association进行分步查询示例
- 在接口DepartmentMapper.java中创建根据id查找部门信息的方法。
public interface DepartmentMapper {
public Department getDeptById(Integer id);
}
- 在DepartmentMapper接口所对应的sql映射文件中编写相应的查找sql语句。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fzl.mybatis.dao.DepartmentMapper">
<select id="getDeptById" resultType="com.fzl.mybatis.bean.Department">
select id,dept_name departmentName from tbl_dept where id=#{id}
</select>
</mapper>
- 在接口(EmoloyeeMapper.java)中创建分步查询的方法。
public Employee getEmpByStep(Integer id);
- 在接口(EmoloyeeMapper.java)所对应的sql映射文件中创建对应的sql语句,并通过association完成分步查询。
<!--
使用association进行分步查询:
1.先按照员工id查询员工信息
2.根据查询员工信息中的d_id值去部门表查出部门信息
3.部门设置到员工中
-->
<resultMap id="MyEmpByStep" type="com.fzl.mybatis.bean.Employee">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/>
<result column="email" property="email"/>
<!--
association定义关联对象的封装规则
select:表明当前属性是调用select指定的方法查出的结果
column:指定将哪一列的值传给这个方法
流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
-->
<association property="dept" select="com.fzl.mybatis.dao.DepartmentMapper.getDeptById" column="d_id"></association>
</resultMap>
<select id="getEmpByStep" resultMap="MyEmpByStep">
select * from tbl_employee where id=#{id}
</select>
分步查询流程为:
先查找出员工的信息,然后使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性.column所指定的列的值,是传到select指定方法的参数。
- 测试。打印员工信息和其所属部门信息。
@Test
public void test1() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try{
EmployeeMapper employeeMapper = openSession.getMapper(EmployeeMapper.class);
// Employee employee = employeeMapper.getEmpById(1);
// System.out.println(employee);
// Employee empAndDept = employeeMapper.getEmpAndDept(1);
// System.out.println(empAndDept.getDept());
Employee empByStep = employeeMapper.getEmpByStep(1);
System.out.println(empByStep);
System.out.println(empByStep.getDept());
}finally{
openSession.close();
}
}
- 测试结果
可以发现,是经过两步完成了查询。
延时加载
在实际开发中,我们会发现,有时候我们只需要获取员工的基本信息,并不需要员工所属部门信息,但是上述操作,会直接将员工信心和其所属部门信息全部都获取到,这会加大系统开销。这时候我们可以在分步查询的基础上添加两个配置,就可以按需加载,这样部门信息就可以在我们使用的时候再去查询,不会再查询Employee对象的时候都将部门信息查出来了。
- 打开mybatis全局配置文件,通过setting添加如下两个配置。
<!-- 显示的指定每个我们需要更改的配置的值,即使他是默认的,防止版本更新 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
- 测试。我们先只打印员工的lastName属性。
@Test
public void test2() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try{
EmployeeMapper employeeMapper = openSession.getMapper(EmployeeMapper.class);
Employee empByStep = employeeMapper.getEmpByStep(1);
System.out.println(empByStep.getLastName());
// System.out.println(empByStep.getDept().getDepartmentName());
}finally{
openSession.close();
}
}
运行结果:
然后测试打印员工部门信息。
@Test
public void test2() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try{
EmployeeMapper employeeMapper = openSession.getMapper(EmployeeMapper.class);
Employee empByStep = employeeMapper.getEmpByStep(1);
System.out.println(empByStep.getLastName());
System.out.println(empByStep.getDept().getDepartmentName());
}finally{
openSession.close();
}
}
运行结果。
可以发现,在第一次只调用lastName属性的时候,并没有查询部门信息,只有在打印部门信息的时候,才执行的查询部门信息的sql代码。