MyBatis-03 关联查询 级联属性 分布查询和延迟加载 collection属性

1.在Mybatis查询中,一条sql查询两个表的数据,可以用到级联属性。例如在员工的属性中加入部门的对象,这样可以用到级联属性来配置:

员工实体类:com.atguigu.mybatis.dao.EmployeeMapper

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

部门实体类:com.atguigu.mybatis.bean.Department

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

配置文件:可以有两种配置方式:级联属性和association定义关联

<!--
		1.联合查询:级联属性封装结果集
	  -->
	<resultMap type="com.atguigu.mybatis.bean.Employee" id="MyDifEmp">
		<id column="id" property="id"/>
		<result column="last_name" property="lastName"/>
		<result column="gender" property="gender"/>
		<result column="did" property="dept.id"/>
		<result column="dept_name" property="dept.departmentName"/>
	</resultMap>

	<!-- 
		2.使用association定义关联的单个对象的封装规则;
	 -->
	<resultMap type="com.atguigu.mybatis.bean.Employee" id="MyDifEmp2">
		<id column="id" property="id"/>
		<result column="last_name" property="lastName"/>
		<result column="gender" property="gender"/>
		<!--  association可以指定联合的javaBean对象
		property="dept":指定哪个属性是联合的对象
		javaType:指定这个属性对象的类型[不能省略]
		-->
		<association property="dept" javaType="com.atguigu.mybatis.bean.Department">
			<id column="did" property="id"/>
			<result column="dept_name" property="departmentName"/>
		</association>
	</resultMap>
	<!--  public Employee getEmpAndDept(Integer id);-->
	<select id="getEmpAndDept" resultMap="MyDifEmp">
		SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
		d.id did,d.dept_name dept_name FROM tbl_employee e,tbl_dept d
		WHERE e.d_id=d.id AND e.id=#{id}
	</select>

这时打印结果:

2.以上查询的sql语句是连接查询,即一条sql查询多个表,这样会导致效率不高,可以将查询改为分步查询和懒加载的方式来处理:即每条sql都只查询一个表,之后在Emp中由association做分步查询,在mybatis的全局配置文件中用setting做懒加载的配置,这样可以达到高效的数据库查询,即当用到哪个表的数据才会执行相关的数据库查询操作,不用就不执行。

具体操作:

部门实体类和员工实体类与上面一致;

mapper的配置:

部门的xml文件中:

<!--public Department getDeptById(Integer id);  -->
	<select id="getDeptById" resultType="com.atguigu.mybatis.bean.Department">
		select id,dept_name departmentName from tbl_dept where id=#{id}
	</select>

员工的xml文件中:注意此时使用的是association分步查询,每个mapper.xml文件中只查询mapper对应的实体类再用association进行关联;

<!-- 使用association进行分步查询:
		1、先按照员工id查询员工信息
		2、根据查询员工信息中的d_id值去部门表查出部门信息
		3、部门设置到员工中;
	 -->
	 
	 <!--  id  last_name  email   gender    d_id   -->
	 <resultMap type="com.atguigu.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指定的方法查出的结果
	 		column:指定将哪一列的值传给这个方法
	 		流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
	 	 -->
 		<association property="dept" 
	 		select="com.atguigu.mybatis.dao.DepartmentMapper.getDeptById"
	 		column="d_id">
 		</association>
	 </resultMap>
	 <!--  public Employee getEmpByIdStep(Integer id);-->
	 <select id="getEmpByIdStep" resultMap="MyEmpByStep">
	 	select * from tbl_employee where id=#{id}
	 </select>
	 
	<settings>
		<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
		<setting name="jdbcTypeForNull" value="NULL"/>
		
		<!--显示的指定每个我们需要更改的配置的值,即使他是默认的。防止版本更新带来的问题  -->
		<setting name="lazyLoadingEnabled" value="true"/>
		<setting name="aggressiveLazyLoading" value="false"/>
	</settings>
	

<!-- 可以使用延迟加载(懒加载);(按需加载) Employee==>Dept: 我们每次查询Employee对象的时候,都将一起查询出来。 部门信息在我们使用的时候再去查询; 分段查询的基础之上加上两个配置: -->

mybatis.config的全局配置文件:配置懒加载

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

效果:

1.开启懒加载模式,只查询员工相关的信息,此时懒加载生效,只发送了一条sql来查询员工信息;


2.开启懒加载,同时查询员工信息和部门信息,则发送两个sql,查询出来两个信息:


3.当要查询部门下的所有员工的信息的时候,就要在部门属性中添加一个list属性,用来存储所有的员工信息:

部门bean:

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

员工bean:

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

部门的xml:

	<!-- collection:分段查询   column 将哪一列的值作为传递的参数-->
	<resultMap type="com.atguigu.mybatis.bean.Department" id="MyDeptStep">
		<id column="id" property="id"/>
		<id column="dept_name" property="departmentName"/>
		<collection property="emps" 
			select="com.atguigu.mybatis.dao.EmployeeMapperPlus.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>

<!-- 扩展:多列的值传递过去:
将多列的值封装map传递;
column="{key1=column1,key2=column2}"
fetchType="lazy":表示使用延迟加载;
- lazy:延迟:用到的时候才发
- eager:立即,马上就发
-->

员工的xml:

	<select id="getEmpsByDeptId" resultType="com.atguigu.mybatis.bean.Employee">
		select * from tbl_employee where d_id=#{deptId}
	</select>

mybatis-condif.xml配置文件中的setting一致;

此时还是懒加载的模式:

即只加载查询相关的信息:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值