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 支持复杂的映射场景,如自定义映射、一对一、一对多关联,以及嵌套结果

相关推荐
ん贤1 小时前
Go channel 深入解析
开发语言·后端·golang
changhong19864 小时前
如何在 Spring Boot 中配置数据库?
数据库·spring boot·后端
月月玩代码6 小时前
Actuator,Spring Boot应用监控与管理端点!
java·spring boot·后端
XPoet7 小时前
AI 编程工程化:Skill——给你的 AI 员工装上技能包
前端·后端·ai编程
码事漫谈8 小时前
从“功能实现”到“深度优化”:金仓数据库连接条件下推技术的演进之路
后端
码事漫谈8 小时前
数据库查询优化中的谓词下推策略与成本感知优化实践
后端
Amour恋空8 小时前
SpringBoot+Lombok+Logback实现日志
spring boot·后端·logback
廋到被风吹走8 小时前
【LangChain4j】特点功能及使用场景
后端·python·flask
毕设源码-邱学长8 小时前
【开题答辩全过程】以 基于Spring Boot的体育场地预约管理系统为例,包含答辩的问题和答案
java·spring boot·后端
青槿吖9 小时前
第二篇:告别XML臃肿配置!Spring注解式IOC/DI保姆级教程,从入门到真香
xml·java·开发语言·数据库·后端·sql·spring