MyBatis 结果映射详解:resultType 与 resultMap
MyBatis 结果映射详解:resultType 与 resultMap
在 MyBatis 中,结果映射是将数据库查询结果集(ResultSet)映射到 Java 对象的关键步骤。MyBatis 提供了两种主要的方式来处理结果映射:resultType 和 resultMap。本文将详细介绍这两种方式的使用场景、配置方法以及最佳实践,帮助开发者更好地理解和应用 MyBatis 的结果映射功能。
1. 结果映射概述
在使用原生的 JDBC 操作时,开发者需要手动处理 ResultSet,将其转换为 Java 对象。MyBatis 通过 resultType 和 resultMap 简化了这一过程,能够自动将查询结果映射到 Java 对象中。
注意:只要一个方法有返回值需要处理,那么 resultType 或 resultMap 必须配置其中一个,但不能同时使用。
2. resultType 的使用
resultType 用于指定 SQL 查询结果的返回类型。它适用于简单的映射场景,尤其是当数据库字段名与 Java 对象属性名一致时。
2.1 返回值是简单类型
当返回值是基本数据类型(如 int、String)时,resultType 直接指定对应的类型别名或全限定名即可。
示例:
int countUsers();
<select id="countUsers" resultType="int">
    SELECT COUNT(*) FROM user
</select>
2.2 返回值是 POJO 对象
当返回值是一个 POJO 对象时,resultType 指定为该 POJO 类的全限定名或别名。
示例:
User queryUserById(Integer id);
<select id="queryUserById" resultType="User">
    SELECT * FROM user WHERE id = #{id}
</select>
2.3 返回值是 List 集合
当返回值是一个 List 集合时,resultType 指定为集合中元素的类型,而不是 List 本身。
示例:
List<User> findAllUsers();
<select id="findAllUsers" resultType="User">
    SELECT * FROM user
</select>
2.4 返回值是 Map
2.4.1 返回单条数据到 Map
当返回值是一条数据并封装到 Map 中时,resultType 指定为 map。MyBatis 会将列名作为 Map 的 key,列值作为 Map 的 value。
示例:
Map<String, Object> selectByIdReturnMap(Integer id);
<select id="selectByIdReturnMap" resultType="map">
    SELECT * FROM user WHERE id = #{id}
</select>
2.4.2 返回多条数据到 Map
当返回值是多条数据并封装到 Map 中时,需要使用 @MapKey 注解指定作为 Map key 的列名。
示例:
@MapKey("id")
Map<Integer, User> selectAllUsersReturnMap();
<select id="selectAllUsersReturnMap" resultType="User">
    SELECT * FROM user
</select>
3. resultMap 的使用
resultMap 是 MyBatis 中最强大且灵活的结果映射方式。它适用于复杂的映射场景,尤其是当数据库字段名与 Java 对象属性名不一致时,或者需要进行高级映射(如一对一、一对多)时。
3.1 解决字段名与属性名不一致的问题
当数据库字段名与 Java 对象属性名不一致时,可以通过 resultMap 手动配置映射关系。
示例:
<resultMap id="userResultMap" type="User" autoMapping="true">
    <id column="id" property="id" />
    <result column="name" property="username" />
</resultMap>
<select id="queryUserById" resultMap="userResultMap">
    SELECT * FROM user WHERE id = #{id}
</select>
说明:
- id标签用于配置主键字段的映射。
- result标签用于配置普通字段的映射。
- autoMapping属性设置为- true时,MyBatis 会自动映射字段名与属性名相同的字段。
在 MyBatis 的 <resultMap> 中,<result column="name" property="username" /> 是否有必要书写,取决于以下两种情况:
1. autoMapping="true" 的作用
- autoMapping="true"表示 MyBatis 会自动将查询结果的列名与实体类的属性名进行映射。
- 如果数据库表的列名(如 name)与实体类的属性名(如username)不一致,则需要显式使用<result>标签指定映射关系。
- 如果列名与属性名一致,则不需要显式书写 <result>标签。
2. 是否需要显式书写 <result column="name" property="username" />
情况 1:列名与属性名不一致
- 如果数据库表的列名是 name,而实体类的属性名是username,则必须显式书写:<result column="name" property="username" />
- 如果不写,MyBatis 无法自动映射,会导致 username属性值为null。
情况 2:列名与属性名一致
- 如果数据库表的列名是 name,实体类的属性名也是name,则不需要显式书写:<!-- 不需要写 <result column="name" property="name" /> -->
- MyBatis 会自动完成映射。
你的代码分析
在你的代码中:
<resultMap id="userResultMap" type="User" autoMapping="true">
    <id column="id" property="id" />
    <result column="name" property="username" />
</resultMap>
- autoMapping="true"表示开启自动映射。
- <id column="id" property="id" />是必须的,因为主键字段需要显式指定。
- <result column="name" property="username" />是否有必要书写,取决于- name和- username是否一致:- 如果 name和username不一致,则必须书写。
- 如果 name和username一致,则可以省略。
 
- 如果 
示例
示例 1:列名与属性名不一致
- 数据库列名:name
- 实体类属性名:username
- 必须显式书写:<result column="name" property="username" />
示例 2:列名与属性名一致
- 数据库列名:name
- 实体类属性名:name
- 不需要显式书写:<!-- 不需要写 <result column="name" property="name" /> -->
总结
- 如果 name和username不一致,则<result column="name" property="username" />是必须的。
- 如果 name和username一致,则可以省略。
在你的代码中,如果 name 和 username 不一致,那么这条配置是必要的;如果一致,则可以删除。
3.2 高级映射
resultMap 还支持一对一、一对多、多对多等高级映射。这些内容将在后续的多表查询部分详细介绍。
4. resultType 与 resultMap 的对比
| 特性 | resultType | resultMap | 
|---|---|---|
| 适用场景 | 简单映射,字段名与属性名一致 | 复杂映射,字段名与属性名不一致 | 
| 配置复杂度 | 简单,直接指定返回类型 | 复杂,需要手动配置映射关系 | 
| 灵活性 | 较低,仅支持简单映射 | 较高,支持复杂映射和高级查询 | 
| 性能 | 较高,适用于简单场景 | 较低,适用于复杂场景 | 
5. 最佳实践
- 简单场景:优先使用 resultType,配置简单且性能较高。
- 复杂场景:使用 resultMap,灵活处理字段名与属性名不一致的问题。
- Map 返回值:
- 单条数据:直接使用 resultType="map"。
- 多条数据:使用 @MapKey注解指定 key 列。
 
- 单条数据:直接使用 
- 自动映射:在 resultMap中开启autoMapping,减少手动配置的工作量。
6. 总结
MyBatis 提供了 resultType 和 resultMap 两种结果映射方式,分别适用于简单和复杂的映射场景。开发者可以根据实际需求选择合适的方式:
- resultType:适用于字段名与属性名一致的简单映射。
- resultMap:适用于字段名与属性名不一致或需要高级映射的复杂场景。
通过合理使用 resultType 和 resultMap,可以大大提高 MyBatis 的开发效率和代码的可维护性。希望本文能帮助您更好地理解和应用 MyBatis 的结果映射功能。如果您有任何问题或建议,欢迎留言讨论!
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号