• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

奋斗的软件工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

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. 最佳实践

  1. 简单场景:优先使用 resultType,配置简单且性能较高。
  2. 复杂场景:使用 resultMap,灵活处理字段名与属性名不一致的问题。
  3. Map 返回值:
    • 单条数据:直接使用 resultType="map"。
    • 多条数据:使用 @MapKey 注解指定 key 列。
  4. 自动映射:在 resultMap 中开启 autoMapping,减少手动配置的工作量。

6. 总结

MyBatis 提供了 resultType 和 resultMap 两种结果映射方式,分别适用于简单和复杂的映射场景。开发者可以根据实际需求选择合适的方式:

  • resultType:适用于字段名与属性名一致的简单映射。
  • resultMap:适用于字段名与属性名不一致或需要高级映射的复杂场景。

通过合理使用 resultType 和 resultMap,可以大大提高 MyBatis 的开发效率和代码的可维护性。希望本文能帮助您更好地理解和应用 MyBatis 的结果映射功能。如果您有任何问题或建议,欢迎留言讨论!

posted on 2025-01-02 17:00  周政然  阅读(777)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3