resultMap对象之间的级联关系[ 一对一关系 ] (二)

MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType就是 mybatis会自己通过反射 根据字段名设置到对应的实例中的属性。

而resultMap则是对外部ResultMap的引用,resultMap就是你自定义的一个映射关系
而且resultMap可以实现一种功能
就是当你是1对多 这种多张表查询的时候 你没办法 通过表连接来实现一个集合设置到一个实例里,但是通过resultMap里可以做到 根据关联的字段 查询到一个集合 然后把集合设置到 那个对象的对应属性。

但是resultType跟resultMap不能同时存在。

 

案例:通过员工id  查询 员工的信息 以及 所在部门信息

    -- emp员工表中存储的是 员工的信息
    -- dept部门表中存储的是部门的信息
    -- 而员工的id只有emp表中有,部门名字也只有dept表中有
    -- 员工表和部门表中的共有属性是:部门编号,部门编号是一样的
    -- 这里要同时查询两张表才能查出来

一个员工对应一个部门,一对一关系。

数据库两张表 :

employee员工表  

 Dept部门表


 

两个表的实体类

package com.mybatis.bean;

/***
 *	部门实体类 
 */
public class Dept {

  private Integer did; //部门id
  private String dname;	//部门名称
	
  //..........省略 set get 方法
}
/**
 * 员工实体类
 */
public class Employee {
  
  //实体类字段建议和数据库字段名一致
  private Integer id; 		 //员工id
  private String name;		 //员工姓名
  private String sex;			 //性别
  private Integer money;		 //工资
	
  //部门实体类 成员变量
  private Dept dept; 
  //...........省略set get 方法
}

两个表的持久层

/**
 * 	Employee 的持久层接口
 *
 */
public interface EmployeeMapper {

	//根据员工id  查询员工信息  以及 员工部门信息
	public abstract Employee findEmpAndDept(Integer id);
	
	/**
	 * 	根据员工id 查询员工信息  以及 员工部门信息
	 * 	利用已经有的select方法 ------->>>> 分步查询
	 */
	public abstract Employee findEmpStep(Integer id);
}
/**
 *	操作部门的DAO接口
 */
public interface DeptMapper {

	//根据部门id查询部门
	public abstract Dept findDeptById(Integer id);
}

 

 

1.第一种解决方式 (使用员工id关联查询两张表格)  并使用  resultMap的级联关系封装结果集

  EmployeeMapper.xml  (员工表SQL映射文件配置)

<mapper namespace="com.mybatis.dao.EmployeeMapper">

 <!-- 自定义实体类的封装规则   第一种方式:级联关系 -->
 <resultMap id="Emp1" type="com.mybatis.bean.Employee" >
  <!-- 主键封装规则-->
  <id column="id" property="id" />
  	
  <!-- 普通字段封装规则 -->
  <result column="name" property="name" />
  <result column="sex" property="sex" />
  <result column="money" property="money" />
  
  <!-- 关联查询,级联属性封装结果集  -->
  <!-- 将部门id和部门名称封装到   dept成员对象中	-->
  <result column="dept_id" property="dept.did"/> <!-- property:dept.did  (封装到dept成员对象  的did字段中) -->
  <result column="dept_name" property="dept.dname"/>
 </resultMap>


 <!-- 根据员工id  查询员工信息  以及 员工部门信息 -->
 <select id="findEmpAndDept" resultMap="Emp1"> <!-- resultMap引用封装规则 -->
  SELECT 
  	e.id, e.name, e.sex, e.money, d.did dept_id, d.dname dept_name 
  FROM 
  	employee e,dept d 
  WHERE 
  	e.id = #{id} AND e.dept_id = d.did
 </select>
</mapper>

controller

SqlSession session = sqlSessionFactory.openSession();
		
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class); //利用反射创建employee的持久层实现类

//查询id为1 的员工信息以及所在部门信息
Employee employee = mapper.findEmpAndDept(1); 

System.out.println(employee.toString());

Employee [id=1, name=tom, money=1200, sex=man, dept=Dept [did=2, dname=运营部]]

 

 

2.第二种方式 (使用员工id关联查询两张表格) 并使用   resultMap封装结果集(association 属性指定联合的javabean对象)

EmployeeMapper.xml

<mapper namespace="com.mybatis.dao.EmployeeMapper"> 
 <!-- 自定义实体类的封装策略   第二种方式:association指定联合的javabean对象  -->
 <resultMap id="Emp2" type="com.mybatis.bean.Employee" >
  <!-- 主键封装规则-->
  <id column="id" property="id" />
  	
  <!-- 普通字段封装规则 -->
  <result column="name" property="name" />
  <result column="sex" property="sex" />
  <result column="money" property="money" />
  
  <!-- association 指定联合的javabean对象 	(关联的对象)
       属性:property :指定联合的javabean对象的属性名    (Employee中的 成员对象dept)
            javaType: 指定java类型
  -->	
  <association property="dept" javaType="com.mybatis.bean.Dept">
    <!-- 定义dept对象封装规则 -->
  	<id column="dept_id" property="did" />
  	<id column="dept_name" property="dname" />
  </association>
  </resultMap>


 <!-- 根据员工id  查询员工信息  以及 员工部门信息 -->
 <select id="findEmpAndDept" resultMap="Emp2"> <!-- resultMap指定封装规则 -->
  SELECT 
  	e.id, e.name, e.sex, e.money, d.did dept_id, d.dname dept_name 
  FROM 
  	employee e,dept d 
  WHERE 
  	e.id = #{id} AND e.dept_id = d.did;
 </select>

</mapper>

controller

String resource = "mybatis_config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);	
		
SqlSession session = sqlSessionFactory.openSession();

EmployeeMapper mapper = session.getMapper(EmployeeMapper.class); //利用反射创建employee的持久层实现类

//直接查询两张表,一次性查询出来
Employee employee = mapper.findEmpAndDept(1); 
System.out.println(employee.toString());

Employee [id=1, name=tom, money=1200, sex=man, dept=Dept [did=2, dname=运营部]]

 

使用两种方式都可以
第一种方式级联关系更加简单,只能关联数据,功能比较单一
第二种方式association功能更加完善, 不仅可以关联数据、还可以进行分步查询

 

3.第三种方式 使用 resultMap封装结果集 并使用其子属性association分步查询

查询出员工的信息,以及部门id和部门名称
       利用已经有的查询方法
           
        1.通过员工的id查询出员工的个人信息           >>>查询员工表  Employee
        2.在通过员工信息中的部门id,查询部门      >>>查询部门表  Dept
                 将两次查询的结果封装到一起

 

DeptMapper.xml  部门表的SQL映射文件

<mapper namespace="com.mybatis.dao.DeptMapper">
  <!--  该xml是 操作Dept部门表的 SQL映射文件 -->
	
  <!-- 按照id查询部门 -->
  <!-- public abstract Dept findDeptById(Integer id) -->
  <select id="findDeptById" resultType="com.mybatis.bean.Dept">
	SELECT * FROM dept where did = #{id}
  </select>

</mapper>

EmployeeMapper.xml (员工表的SQL映射文件,实现持久层接口中的分步查询方法 findEmpStep)


<mapper namespace="com.mybatis.dao.EmployeeMapper">

 <!-- 定义对象封装规则 -->
 <resultMap  id="EmpByStep" type="com.mybatis.bean.Employee">
   <id column="id" property="id" />  <!-- 主键字段封装 -->
   		
   <!-- 普通字段封装规则 -->
   <result column="name" property="name" />
   <result column="sex" property="sex" />
   <result column="money" property="money"/>
   		
   <!--  association 分步查询 -->
   <!-- 
   	 property: 指定联合的bean对象(Employee的成员对象dept)
   	 select:指定关联的dept属性,是调用哪一个SQL映射文件中的方法查询出来的结果
   		  索引SQL映射文件和方法 : (SQL映射文件的名称空间+调用的方法名)
   	 column: 指定将那一列的结果集传递给这个方法  (将结果集中的dept_id字段传递给此方法)
   	-->
   <association property="dept" select="com.mybatis.dao.DeptMapper.findDeptById" column="dept_id">
   </association>
   
 </resultMap>
 
 <!-- 分步查询 -->
 <!-- public abstract Employee findEmpStep(Integer id); -->
 <select id="findEmpStep" resultMap="EmpByStep">  <!-- resultMap引用结果集封装规则  -->
 	select * from employee where id = #{id}
 </select>
	
</mapper> 

controller

String resource = "mybatis_config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		
SqlSession session = sqlSessionFactory.openSession();
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class); //利用反射创建employee的持久层实现类


//分步查询:  1.先查询员工信息,获取到部门id --->>   2.在调用部门持久层的findDeptById方法查询部门信息
Employee empStep = mapper.findEmpStep(1);

System.out.println(empStep.toString());		

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值