resultType适用于字段名与属性名严格遵循下划线转驼峰规则且mapUnderscoreToCamelCase已开启的场景;resultMap是处理命名不一致、类型转换、嵌套查询等复杂映射的唯一可靠方案。

resultType 适合字段名和属性名完全一致的场景
当数据库列名(如 user_name)和 Java 实体类属性名(如 userName)能靠 MyBatis 默认驼峰映射自动对齐时,resultType 最省事。它底层走的是自动反射 + 字段匹配,没额外配置负担。
但注意:这个“自动对齐”依赖两个前提——mapUnderscoreToCamelCase 必须开启(默认关闭),且字段与属性名必须满足下划线转驼峰规则。比如 create_time → createTime 可以,但 usr_nm → usrNm 就不行。
- 开启方式:在
mybatis-config.xml中加<setting name="mapUnderscoreToCamelCase" value="true"/> - 不生效常见原因:配置写错位置(必须在
<configuration>下,不能放在<environments>里) - Spring Boot 用户别去配 XML,改
application.yml:mybatis.configuration.map-underscore-to-camel-case: true
resultMap 是处理不一致映射的唯一可靠方案
只要出现以下任意一种情况,resultType 就无能为力,必须上 resultMap:
- 数据库字段名和属性名毫无规律(如
u_name→loginId) - 需要做类型转换(如数据库存
TINYINT(1),Java 用Boolean) - 要嵌套查询或关联集合(
<association>/<collection>) - 字段需做表达式计算(如
CONCAT(first_name, ' ', last_name)映射到fullName)
示例片段:
<resultMap id="userMap" type="User">
<id property="id" column="u_id"/>
<result property="loginId" column="u_name"/>
<result property="isActive" column="status" javaType="boolean"/>
</resultMap>
<select id="selectUser" resultMap="userMap">
SELECT u_id, u_name, status FROM users WHERE id = #{id}
</select>
column 和 property 写错是 runtime 静默失败的主因
MyBatis 不会在启动时校验 resultMap 里的 column 是否真存在于结果集,也不会检查 property 是否在目标类中可写。错一个字母,就导致对应字段为 null 或抛 ReflectionException,而且往往只在特定数据路径下暴露。
-
column值必须和 SQL 执行后实际返回的列名严格一致(注意别名!) -
property必须是 JavaBean 的 setter 方法名去掉set后的首字母小写形式(如setLoginId()→loginId) - 如果用了
AS别名,column就得写别名,不是原始字段名 - 建议在 SQL 里显式写别名,和
resultMap一一对照,避免依赖驱动返回的原始列名
复杂映射别硬扛,优先拆成多个 resultMap
一个大而全的 resultMap 看似省事,但维护成本高、复用性差、调试困难。尤其涉及多表 join + 多层嵌套时,容易陷入字段冲突和别名污染。
- 把共用部分抽成
<sql>片段,或用<resultMap extends="baseMap">继承 - 一对一关联用
<association resultMap="xxx">,别把所有字段平铺在一个 map 里 - 集合字段用
<collection ofType="Item" resultMap="itemMap">,确保子映射独立可测 - SQL 返回字段过多时,宁可多写几个
SELECT子句,也别靠*加一堆<result>硬凑
最常被忽略的是 resultMap 的作用域——它只对当前 <mapper> 文件内有效,跨文件引用要加 namespace 前缀,比如 com.example.UserMapper.userMap。漏写 namespace 是调用不到自定义映射的隐形杀手。










