优先使用resultMap显式映射字段与属性,因其不依赖别名、配置或简单查询,支持命名差异、类型转换和嵌套扩展,XML中定义清晰可复用。

当数据库字段名(如 user_name)和 Java 实体类属性名(如 userName)不一致时,MyBatis 默认无法自动匹配,对应属性会为 null。解决的核心是**显式建立字段(column)与属性(property)的映射关系**,resultMap 是最规范、最可控、也最推荐的方式。
为什么优先选 resultMap 而不是其他方式
它不依赖 SQL 别名书写、不依赖全局配置开关、不局限于简单查询,而是把映射逻辑集中定义、可复用、可校验(虽运行时才报错,但结构清晰)。尤其适合中大型项目或需要长期维护的代码。
- 支持任意命名差异:比如
usr_nm→loginId、is_active→enabled - 天然兼容类型转换:如数据库
TINYINT(1)映射为 JavaBoolean - 可扩展性强:后续加嵌套对象(
<association>)、集合(<collection>)无需重构 - XML 中定义,与 SQL 分离,职责更清晰
resultMap 基础写法与关键细节
在 Mapper XML 文件中定义:
<resultMap id="userMap" type="com.example.entity.User">
<id property="id" column="u_id"/>
<result property="loginId" column="u_name"/>
<result property="enabled" column="status" javaType="boolean"/>
</resultMap>
<select id="selectById" resultMap="userMap">
SELECT u_id, u_name, status FROM users WHERE u_id = #{id}
</select>
注意三点:
立即学习“Java免费学习笔记(深入)”;
-
column 值必须等于 SQL 执行后实际返回的列名:如果用了
AS user_alias,这里就得写user_alias,不能写原始字段名 -
property 必须是 setter 方法去掉
set后首字母小写的形式:例如有setLoginId(String),就写loginId -
主键用
<id>,普通字段用<result>:虽非强制,但有助于 MyBatis 优化一级/二级缓存行为
配合使用能进一步提效的技巧
单独用 resultMap 已足够可靠,但搭配以下做法可减少出错、提升可维护性:
- SQL 中统一用别名明确语义,如
SELECT u_id AS id, u_name AS login_id,再在 resultMap 中按别名映射,避免混淆原始字段 - 给
resultMap的id取有意义的名字(如userWithDeptMap),方便多处复用或继承 - 复杂对象可基于已有 resultMap 继承扩展:
<resultMap id="userDetailMap" type="User" extends="userMap"> - Spring Boot 项目中,可在
@Select上直接用@Results注解替代 XML,适合单个简单映射场景
什么情况下可以不用 resultMap
如果你的项目满足全部条件,可考虑更轻量方案:
- 所有字段都严格遵循
snake_case→camelCase规则(如create_time→createTime) - 已开启全局驼峰转换:
mybatis.configuration.map-underscore-to-camel-case=true - 没有类型转换、没有嵌套、没有动态列计算
此时用 resultType 最省事;但只要有一处破例,就建议回归 resultMap,避免混用导致逻辑割裂。


















