Mapper.xml继承机制
Mybatis实际上隐藏了一个功能:Mapper.xml可以继承,这个在官方文档中并没有提到过,不过在这个issue (commit)里提到过。
Statement覆盖
利用Mapper.xml的继承机制,我们可以做到ChildMapper覆盖ParentMapper中select
、insert
、delete
、update
。下面举例说明:
Interface:
@MybatisMapper
public interface ParentMapper {
String selectFoo();
String selectBar();
}
@MybatisMapper
public interface ChildMapper extends ParentMapper {
String selectLoo();
}
Mapper.xml:
<mapper namespace="me.chanjar.mybatislearn.inherit.statement.ParentMapper">
<select id="selectFoo" resultType="String">
SELECT 'Foo From Parent'
FROM dual
</select>
<select id="selectBar" resultType="String">
SELECT 'Bar From Parent'
FROM dual
</select>
</mapper>
<mapper namespace="me.chanjar.mybatislearn.inherit.statement.ChildMapper">
<!-- 覆盖 Parent.selectFoo的定义 -->
<select id="selectFoo" resultType="String">
SELECT 'Foo From Child'
FROM dual
</select>
<!-- 不覆盖 Parent.selectBar的定义 -->
<!-- 自己的 Child.selectLoo的定义 -->
<select id="selectLoo" resultType="String">
SELECT 'Loo From Child'
FROM dual
</select>
</mapper>
规律可以总结为:
- ParentMapper.xml中有,ChildMapper.xml中没有,ChildMapper沿用ParentMapper.xml中的定义
- ParentMapper.xml中有,ChildMapper.xml中也有,ChildMapper使用ChildMapper.xml中的定义
- ParentMapper.xml中没有,ChildMapper.xml中有,ChildMapper使用ChildMapper.xml中的定义
ResultMap覆盖
Mapper.xml继承机制只针对statement有效,对于sql
、resultMap
是无效的。
如果要在ChildMapper.xml中覆盖这些,必须要先覆盖ParentMapper.xml中的statement,然后让这些statement使用新的sql
、resultMap
等。
下面举例一个给ITEM表添加字段,但是不修改原来的ItemMapper的例子:
Model:
public class Item {
private Integer id;
private String title;
// setter and getter ...
}
public class ItemEx extends Item {
private String name;
// setter and getter ...
}
Interface:
@MybatisMapper
public interface ItemMapper {
Item getById(@Param("id") Long id);
}
@MybatisMapper
public interface ItemExMapper extends ItemMapper {
}
Mapper.xml:
<mapper namespace="me.chanjar.mybatislearn.inherit.resultmap.ItemMapper">
<select id="getById" resultMap="Item">
select
*
from item where id = #{id}
</select>
<resultMap id="Item" type="me.chanjar.mybatislearn.inherit.resultmap.Item" autoMapping="true">
<id property="id" column="id" />
</resultMap>
</mapper>
<mapper namespace="me.chanjar.mybatislearn.inherit.resultmap.ItemExMapper">
<!-- 如果这里不写一遍,就会用到ItemMapper.getById的定义,resultMap就不会是ItemEx-->
<select id="getById" resultMap="Item">
select
*
from item where id = #{id}
</select>
<resultMap id="Item" type="me.chanjar.mybatislearn.inherit.resultmap.ItemEx" autoMapping="true">
<id property="id" column="id" />
</resultMap>
</mapper>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。