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 的结果映射功能。如果您有任何问题或建议,欢迎留言讨论!