mybatis中resultmap的extends用于xml层声明式复用,通过继承基础映射(如id、createtime)避免重复配置,支持多层扩展(如userwithprofileresult→userresult→baseentityresult),需配合命名空间和typealias防冲突,仅适用于语义一致的静态字段映射。

在持久层设计中,extends关键字本身不直接出现在 Java 实体类或 DAO 层的继承逻辑里——它真正发力的地方,是在 MyBatis 的 resultMap 配置体系中。这里的 extends 是 XML 层的声明式复用机制,不是 Java 类继承语法,但效果高度一致:一次定义、多处继承、避免重复映射。
用 resultMap extends 抽取基础映射骨架
多数业务实体都共享主键、创建时间、更新时间、状态等字段。若每个 SQL 查询都手动写一遍这些 <id></id> 和 <result></result>,极易出错且难以维护。正确做法是先定义一个通用基础 resultMap:
- 在统一的 mapper XML(如
BaseMapper.xml)中声明:<resultmap id="BaseEntityResult" type="com.example.BaseEntity"><br><id property="id" column="id"></id><br><result property="createTime" column="create_time"></result><br><result property="updateTime" column="update_time"></result><br></resultmap>
- 所有具体实体的 resultMap 都通过
extends="BaseEntityResult"继承它,只补充自身特有字段
按业务维度分层继承,支持灵活组合
复用不止于“纵向继承”,还可构建“横向扩展链”。例如:
-
UserResult→ extendsBaseEntityResult(含 id/createTime) -
UserWithProfileResult→ extendsUserResult(再嵌套<association></association>映射 profile) -
UserWithOrdersResult→ extendsUserResult(嵌套<collection></collection>映射 orders)
这样,基础字段永远只维护一处;新增关联查询时,只需新建子 resultMap,复用已有结构,不碰原始定义。
配合 typeAlias 与命名空间,消除 ID 冲突风险
多个 mapper 文件中若都定义 id="BaseResult",会因全局唯一性导致覆盖。安全做法是:
- 为每个 mapper 设置
namespace(如namespace="com.example.UserMapper") - 引用时使用完整路径:
extends="com.example.BaseMapper.BaseEntityResult" - 在
mybatis-config.xml中配置typeAliases,让 type 属性可写简名(如type="User"),提升可读性
避免滥用:哪些不该用 extends 复用?
不是所有共性都适合用 resultMap extends 拆解:
- 仅 1–2 个 SQL 用到的字段组合 → 直接内联更清晰,不必强行抽取
- 字段语义不同但列名相同(如
status在用户表是启用状态,在订单表是支付状态)→ 应拆成独立 resultMap,避免语义混淆 - 动态 SQL 频繁变化的映射(如条件列随参数浮动)→ extends 不支持条件分支,此时更适合用
<sql></sql>片段 +<include></include>
本质上,resultMap extends 复用的是静态、稳定、语义一致的列-属性绑定关系。它不是万能胶,而是精准手术刀。











