MyBatis(12)MyBatis 映射文件中的 resultMap

MyBatis 的 resultMap 是一种高级映射策略,用于处理复杂的SQL查询结果和Java对象之间的映射关系。resultMap 提供了比 auto-mapping 更为灵活的映射方式,它允许开发者显式指定数据库列和Java对象属性之间的映射关系,甚至可以处理复杂的数据结构,如关联(一对一、一对多)和集合。

resultMap 基本用法

在 MyBatis 的映射文件中,可以通过 <resultMap> 标签定义一个 resultMap<resultMap> 标签有一个 id 属性,用于标识这个 resultMap 的唯一标识符,这样在 <select><insert><update><delete> 等操作中就可以引用这个 resultMap

xml 复制代码
<resultMap id="userResultMap" type="User">
    <id column="id" property="id" />
    <result column="user_name" property="userName" />
    <result column="email" property="email" />
</resultMap>

在上面的示例中,resultMap 定义了一个映射,将数据库中的 iduser_nameemail 列映射到 Java 对象 UseriduserNameemail 属性上。

处理复杂映射

resultMap 不仅可以处理简单的列到属性的映射,还可以处理一对一、一对多的关联关系。

  • 一对一映射 (使用 <association> 标签)
xml 复制代码
<resultMap id="userDetailResultMap" type="UserDetail">
    <id column="id" property="id" />
    <result column="username" property="username" />
    <association property="address" javaType="Address">
        <id column="address_id" property="id"/>
        <result column="street" property="street"/>
        <result column="city" property="city"/>
    </association>
</resultMap>
  • 一对多映射 (使用 <collection> 标签)
xml 复制代码
<resultMap id="userOrdersResultMap" type="User">
    <id column="id" property="id" />
    <result column="username" property="username" />
    <collection property="orders" ofType="Order">
        <id column="order_id" property="id"/>
        <result column="order_date" property="orderDate"/>
        <result column="amount" property="amount"/>
    </collection>
</resultMap>

深入源码解析

在 MyBatis 初始化过程中,它会解析映射文件中的 <resultMap> 标签,创建 ResultMap 对象并存储在 Configuration 对象的 resultMaps 集合中。ResultMap 对象中包含了映射的详细信息,如映射的类型、属性名、列名等。

当执行查询操作并需要映射结果集到Java对象时,MyBatis 将利用这些 ResultMap 对象来进行映射处理。

DefaultResultSetHandler

DefaultResultSetHandler 是 MyBatis 中处理结果集映射的核心类,它的 handleResultSets 方法负责将 JDBC 的 ResultSet 转换成Java对象。

java 复制代码
private List<Object> handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds) throws SQLException {
  final DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
  skipRows(rsw.getResultSet(), rowBounds);
  while (resultContext.getResultCount() < rowBounds.getLimit() && rsw.getResultSet().next()) {
    final ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, null);
    final Object rowValue = getRowValue(rsw, discriminatedResultMap, null);
    storeObject(resultHandler, resultContext, rowValue, null, rsw.getResultSet());
  }
  return resultContext.getResultList();
}

getRowValue 方法中,MyBatis 会根据 ResultMap 中定义的映射关系,从 ResultSet 中读取数据,并通过反射填充到目标对象的相应属性。

总结

通过 resultMap,MyBatis 提供了一种强大而灵活的方式来处理从数据库查询结果到Java对象的映射。resultMap 支持复杂的映射场景,如自定义映射、一对一、一对多关联,以及嵌套结果

相关推荐
程序员-珍18 分钟前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
liuxin3344556635 分钟前
教育技术革新:SpringBoot在线教育系统开发
数据库·spring boot·后端
bug菌2 小时前
Java GUI编程进阶:多线程与并发处理的实战指南
java·后端·java ee
夜月行者3 小时前
如何使用ssm实现基于SSM的宠物服务平台的设计与实现+vue
java·后端·ssm
Yvemil73 小时前
RabbitMQ 入门到精通指南
开发语言·后端·ruby
sdg_advance3 小时前
Spring Cloud之OpenFeign的具体实践
后端·spring cloud·openfeign
猿java4 小时前
使用 Kafka面临的挑战
java·后端·kafka
碳苯4 小时前
【rCore OS 开源操作系统】Rust 枚举与模式匹配
开发语言·人工智能·后端·rust·操作系统·os
kylinxjd4 小时前
spring boot发送邮件
java·spring boot·后端·发送email邮件
2401_857439697 小时前
Spring Boot新闻推荐系统:用户体验优化
spring boot·后端·ux