- Mybaties的继承映射策略是将整个继承树的所有实例保存在一个数据表中,为了有效的区分不同记录属于那个实例,Mybaties需要额外定义一个辨别者列——该列中不同的值代表不同的实例。
- 一个例子:
数据库表字段为:
其中,emp_type定义为辨别者列,这一个表中保存两个实例,Employee与Manager。其中Manager是Employee的子类。
EmployeeMapper配置映射map为:
<resultMap id="employeeMap" type="employee">
<id column="emp_id" property="id" />
<result column="emp_name" property="name"/>
<result column="emp_pass" property="pass"/>
<result column="emp_salary" property="salary"/>
<association property="manager" javaType="manager"
column="mgr_id" select="com.yg.dao.EmployeeMapper.get"
fetchType="lazy"
/>
<!-- 使用select指定的select语句去抓取关联实体,将当前实体的emp_id列的值作为参数传给select语句,ofType属性指定关联实体(集合元素)的类型-->
<collection property="attends" javaType="ArrayList"
ofType="attend" column="emp_id"
select="com.yg.dao.AttendMapper.findByEmpId"
fetchType="lazy"/>
<!-- 使用select指定select语句去赚取关联实体,将当前实体的emp_id列的值作为参数传给select语句,OfType属性指定关联实体(集合元素)的类型-->
<collection property="payments" javaType="ArrayList"
ofType="payment" column="emp_id"
select="com.yg.dao.PaymentMapper.findByEmp"
fetchType="lazy"/>
<!-- 定义辨别者列,列名为emp_type-->
<discriminator javaType="int" column="emp_type">
<case value="2" resultMap="com.yg.dao.ManagerMapper.managerMap"/>
</discriminator>
</resultMap>
ManagerMapper配置映射为:
<resultMap id="managerMap" type="manager" extends="com.yg.dao.EmployeeMapper.employeeMap">
<result column="dept_name" property="dept"/>
<collection property="employees" javaType="ArrayList"
ofType="employee" column="emp_id"
select="com.yg.dao.EmployeeMapper.findByMgrId"
fetchType="eager"/>
<collection property="checks" javaType="ArrayList"
ofType="checkBack" column="emp_id"
select="com.yg.dao.CheckBackMapper.getCheckBackByManager"
fetchType="lazy"/>
</resultMap>
- 对于父类的映射配置中,一定要配置辨别者列的映射规则,通过添加
discriminator
标签定义辨别者列,它支持4个属性:
- column:指定辨别者的数据库列名
- javaType:指定该辨别者对应的JAVA类型
- jdbcType:指定该辨别者列对应的JDBC类型
- typeHandler:指定处理该辨别者列的类型处理器。
- 辨别者列通常指定为int类型,还需要为
<discriminator>
指定<case>
子元素,该子元素指定不同的值代表不同的类。<case>
支持的属性:
- value:指定一个值,代表一个类型
- resultType:指定一个类,不同的值代表不同的类。value和resultType就指定了值与类的对应关系。
- resultMap:指定一个结果为映射的id,该结果映射负责完成子类的映射。
<case>
标签中的resultType与resultMap只需要指定一个就可以了。如果指定的是<resultType>
那么还需要添加<result>
子元素来完成列名和属性名之间的映射。- 重点:如果父类指定resultMap为子类映射,那么负责子类的映射resultMap就需要指定extends属性。resultMap标签中的extends属性用于映射继承关系的类时使用。
上面例子中,指定的extends="…employeeMap"就代表该结果集映射继承了employeeMap——千万不要忘记指定该extends属性,否则这两个Map就是完全独立的两个映射结果集,这将导致映射子类时,丢失父类的相关属性值。