一对一映射
[⚠] 重中之重
配置结果集映射,只用看 SQL 执行结果,不看 SQL 语句!
Table 的列名与 PO 类的属性名的不同,只是一个小 case。<resultMap>
真正的作用和价值并非在此,而是在于『关系映射』。
使用自定义映射的第二个,也是更重要的原因是:关联映射 。
两张表的一对一映射在类与类的关系上体现为 一个类「持有」另一个类。双向的一对一映射则表现为 两个类互相「持有」。
持有方所对应的表为『从表』,被持有方所对应的表为『主表』。association
元素用于 从表 方。
association
元素的常用属性有:
属性 | 说明 |
---|---|
property 属性 | 表示所映射对象的属性名。 |
column 属性 | 表示表的列名,此处必为 外键列 。 |
javaType 属性 | 表示属性所对应的类型名称。 |
jdbcType 属性 | 表示表的列的数据类型。 |
select 属性 | 表示为了获取关联对象,所调用的另一条 MyBatis select 语句的 id 。 |
第一种写法:传统写法
<mapper namespace="demo.dao.EmployeeMapper">
<resultMap id="BaseResultMap" type="demo.bean.po.Employee">
<id ... />
<result ... />
...
<association property="department" javaType="demo.bean.po.Department">
<id column="deptno" property="deptno" jdbcType="INTEGER"/>
<result column="dname" property="dname" jdbcType="VARCHAR"/>
<result column="loc" property="loc" jdbcType="VARCHAR"/>
</association>
<select id="..." resultMap="BaseResultMap">
</mapper>
第二种写法:调用法
<mapper namespace="demo.dao.EmployeeMapper">
<resultMap id="BaseResultMap" type="demo.bean.po.Employee">
<id ... />
<result ... />
...
<association property="department"
column="deptno"
javaType="demo.bean.po.Department"
select="demo.dao.DepartmentMapper.selectByPrimaryKey"/>
</resultMap>
<select id="..." resultMap="BaseResultMap">
</mapper>
一对多映射
一对多的映射在类与类的关系上体现为:一个类持有另一个类的一个对象,另一个类持有这个类的对象集合。
如果一对多映射是单向的,则只会使用到 collection 元素;如果一对多映射是双向的,那么还会使用到前面所说的 association 元素。
collection 元素的常用属性有:
属性 | 说明 |
---|---|
property 属性 | 表示所映射对象的属性名。 |
column 属性 | 表示表的列名,此处必为 外键列 |
javaType 属性 | 表示属性所对应的类型名称,此处必为某种集合类型 |
ofType 属性 | 表示集合当中的单元类型 |
select 属性 | 表示为了获取关联对象,所调用的另一条 MyBatis select 语句的 id |
第一种写法:
<resultMap id="xxx" type="Department">
<id column="deptno" property="deptno"/>
<result column="dname" property="dname"/>
<result column="loc" property="loc"/>
<collection property="employeeList" ofType="Employee">
<id column="empno" property="empno"/>
<result column="ename" property="ename"/>
<result column="job" property="job"/>
<result column="mgr" property="mgr"/>
<result column="hiredate" property="hiredate"/>
<result column="sal" property="sal"/>
<result column="comm" property="comm"/>
<result column="deptno" property="deptno"/>
</collection>
</resultMap>
<select id="selectByPK" parameterType="int" resultMap="xxx">
select dept.deptno deptno,
dept.dname dname,
dept.loc loc,
emp.empno empno,
emp.ename ename,
emp.job job,
emp.mgr mgr,
emp.hiredate hiredate,
emp.sal sal,
emp.comm com
from dept,
emp
where dept.deptno = emp.deptno
and dept.deptno = #{deptno}
</select>
第二种写法:
<mapper namespace="demo.dao.DepartmentMapper">
<resultMap id="BaseResultMap" type="demo.bean.po.Department">
<id ... />
<result ... />
...
<collection column="deptno"
javaType="java.util.List"
ofType="demo.bean.po.Employee"
property="employeeSet"
select="demo.dao.EmployeeMapper.selectByPK"/>
</resultMap>
<select ...>
多对多映射
MyBatis 并没有提供专门的元素用于多对多方案,采取了一种「聪明」的办法,将「三张表」的多对多关系转化为「两张表」的一对多关系。
所以,在多对多关系中,使用的仍然是 collection
元素。
例如:
<mapper namespace="demo.dao.DepartmentMapper">
<resultMap id="BaseResultMap" type="demo.bean.po.Department">
<id ... />
<result ... />
...
<collection column="deptno"
javaType="java.util.Set"
ofType="demo.bean.po.Employee"
property="employeeSet"
select="demo.dao.EmployeeMapper.selectByDeptno"/>
</resultMap>
<select ...>
<resultMap> 的继承
<!-- 逻辑上『父类』 -->
<resultMap id="BaseResultMap" type="com.woniu.demo.dao.po.Employee">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="job" jdbcType="VARCHAR" property="job"/>
<result column="manager_id" jdbcType="BIGINT" property="managerId"/>
<result column="hire_date" jdbcType="DATE" property="hireDate"/>
<result column="salary" jdbcType="INTEGER" property="salary"/>
<result column="commission" jdbcType="INTEGER" property="commission"/>
</resultMap>
<!-- 逻辑上的『子类1』 -->
<resultMap id="ResultMapSimple" type="com.woniu.demo.dao.po.Employee" extends="BaseResultMap">
<result column="department_id" jdbcType="BIGINT" property="departmentId"/>
</resultMap>
<!-- 逻辑上中的『子类2』 -->
<resultMap id="ResultMapComplex" type="com.woniu.demo.dao.po.Employee" extends="BaseResultMap">
<association property="department"
column="department_id"
javaType="com.woniu.demo.dao.po.Department"
select="com.woniu.demo.dao.DepartmentDao.selectByPrimaryKey" fetchType="lazy"/>
</resultMap>