Content Table

MyBatis 的 ResultMap 注意事项

MyBatis 的 ResultMap 比较灵活,使用时需要注意以下几点:

  • ResultMap 中 <result> 的 property 对应 Bean 的属性名,column 对应 SELECT 的字段名:
    • column 在 SELECT 中字段中:
      • 正确: property 对应的属性存在时正确
      • 报错: property 对应的属性不存在时报错
      • 说明: 没有写相关 <result> 时不报错,Bean 有与 column 同名属性时自动设置属性的值,没有时忽略
    • column 不在 SELECT 中字段中:
      • 正确: property 对应的属性存在时不报错
      • 正确: property 对应的属性不存在时不报错
    • 结果: 只要 column 在 SELECT 字段中就需要注意,否则可忽视:
  • SELECT 的字段名和 ResultMap 里属性名相同时,可以不用写 <result>,MyBatis 会自动映射对应的 column 和 property,也就是说如果 SELECT 的字段名和 Bean 的属性名都是同名的,即使 ResultMap 为空,Bean 的属性都会自动设置好,例如下面的 id 和 info 都注释掉了,它们的属性值仍然被正确的设置了
    • 但是,如果 ResultMap 中使用了 <collection> 或者 <association>,只有明确使用 <result> 或者 <id> 设置的属性会被赋值,Bean 中其他属性不会被赋值,也就是自动映射此时默认是关闭的,要开启的话需要在 resultMap 中设置属性 autoMapping="true",可参考 MyBatis Auto Mapping,但是也需要手动写 <id> 标签,否则就可能出问题 (不能正确分组)
  • SELECT 中的字段可以比 ResultMap 里的 <result> 多或者少
  • SELECT 的字段名和 ResultMap 中 <result> 的 property 不同时,需要使用 column 进行映射
  • 自动映射:
    • if column name are equals java bean field name ignore case, then auto mapping works
    • for nested collection/association, we need to add autoMapping=true manually
    • if column name or alias are different from java bean field name, we need to map them manually

下面的代码能够正常运行,对这几条进行了演示:

Java Bean:

1
2
3
4
5
6
7
public class Demo {
private int id;
private String info;
private boolean marked;

// Getters and setters
}

SQL:

1
2
3
<select id="findDemoById" parameterType="int" resultMap="DemoResultMap">
SELECT id, info, is_marked FROM demo WHERE id=#{id}
</select>

ResultMap:

1
2
3
4
5
6
7
8
9
<resultMap id="DemoResultMap" type="Demo">
<!--<id property="id" column="id"/>-->
<!--<result property="info" column="info"/>-->

<result property="marked" column="is_marked"/>

<!-- extra 在 SELECT 的字段名和 Bean 的属性里都不存在: 不报错,忽略即可 -->
<result property="extra" column="extra"/>
</resultMap>