MyBatis实战指南(五)结果映射

MyBatis实战指南(五)结果映射

  • 前言
  • 一、什么是结果映射?
  • 二、结果映射的类型与使用场景
    • 1. 基础映射:自动映射的三种方式
      • 1.1 列名与属性名完全一致:纯自动映射
      • 1.2 列名与属性名不一致:SQL 别名适配
      • 1.3 列名与属性名复杂映射:resultMap 显式配置(推荐方案)
    • 2. resultType vs resultMap
    • 3. resultMap 高级应用:关联查询与复杂关系映射
      • 3.1 一对一关联:用户与角色映射
      • 3.2 一对多关联:用户与订单映射
    • 4. 实战部分 resultMap 的使用


前言

  • 在上一篇博客中,我们深入探讨了MyBatis XML实战相关内容,详细讲解了如何利用MyBatis实现MySQL数据库的增删查改操作,剖析了SQL元素的运用以及从SqlSessionFactory中获取SqlSession的具体流程
  • 本篇博客将聚焦于结果映射这一核心主题,展开全面且深入的解析。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的MyBatis实战指南知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12969707.html?spm=1001.2014.3001.5482


一、什么是结果映射?

结果映射就是MyBatis把数据库查询结果(比如表中的行和列)转换成Java对象的过程。

就像翻译官把英文单词(数据库列名)翻译成中文(Java对象属性),让Java程序能读懂数据库的数据。

二、结果映射的类型与使用场景

1. 基础映射:自动映射的三种方式

MyBatis 的核心能力之一是将数据库查询结果映射到 Java 对象,根据列名与属性名的匹配关系,有以下三种核心方案:

1.1 列名与属性名完全一致:纯自动映射

实现方式
只需在 SQL 映射文件中指定 resultType 为目标 Java 类,MyBatis 会自动按列名匹配属性名完成映射。

<select id="getUserById" resultType="com.example.User">
  select id, name, age from user_table where id=#{id}
select>

底层原理
MyBatis 通过反射获取 Java 类的属性名,并与查询结果的列名(不区分大小写)进行匹配。若数据库使用下划线命名(如 user_name),Java 使用驼峰命名(如 userName),需在 MyBatis 全局配置中开启 mapUnderscoreToCamelCase 开关:

<configuration>
  <settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
  settings>
configuration>

适用场景

  • 数据库设计遵循驼峰命名法(或开启下划线转驼峰),且表结构简单。

1.2 列名与属性名不一致:SQL 别名适配

实现方式
在 SQL 中用 AS 给列起别名,使别名与 Java 属性名一致,无需额外配置。

<select id="getUserByName" resultType="com.example.User">
  select user_id AS id, user_name AS userName, create_time AS createTime 
  from user_table where user_name=#{name}
select>

注意事项

  • 别名需严格匹配 Java 属性名(包括大小写,除非开启驼峰映射)。
  • 适合单表查询或简单多表查询,若别名过多会导致 SQL 可读性下降。

1.3 列名与属性名复杂映射:resultMap 显式配置(推荐方案)

实现方式
通过 resultMap 标签定义列与属性的映射规则,支持主键、普通字段、复杂关系的配置。


<resultMap id="userResultMap" type="com.example.User">
  
  <id property="id" column="user_id" jdbcType="BIGINT"/>
  
  <result property="userName" column="user_name" jdbcType="VARCHAR"/>
  <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
  
  <result property="status" column="status_code" typeHandler="com.example.StatusTypeHandler"/>
resultMap>


<select id="getUserDetail" resultMap="userResultMap">
  select user_id, user_name, create_time, status_code from user_table where id=#{id}
select>

核心标签解析

  • :映射主键字段,MyBatis 会用其值作为对象标识,提升缓存效率和对象比较准确性。
  • :映射普通字段,property 对应 Java 属性名,column 对应数据库列名。
  • jdbcType:可选参数,指定数据库列类型,避免类型转换错误(如 NULL 值处理)。

2. resultType vs resultMap

对比项 resultType(自动映射) resultMap(手动映射)
配置量 零配置,仅需指定类型 需要显式定义映射规则,复杂场景配置量较大
列名匹配 依赖列名、别名或驼峰映射规则 完全自定义映射,支持任意列名与属性名的对应
复杂关系支持 仅支持单表数据,无法处理关联查询 支持一对一(association)、一对多(collection)、多对多关系
性能影响 反射效率略高(无额外解析配置的开销) 首次解析 resultMap 有开销,但后续可复用配置
典型场景 单表查询、接口返回简单 DTO 多表关联查询(如用户-角色关联)、属性需要类型转换或表达式处理

3. resultMap 高级应用:关联查询与复杂关系映射

3.1 一对一关联:用户与角色映射

假设用户表(user_table)与角色表(role_table)通过 role_id 关联:

<resultMap id="userWithRoleMap" type="com.example.User">
  <id property="id" column="user_id"/>
  <result property="userName" column="user_name"/>
  
  <association property="role" javaType="com.example.Role">
    <id property="id" column="role_id"/>
    <result property="roleName" column="role_name"/>
  association>
resultMap>

<select id="getUserWithRole" resultMap="userWithRoleMap">
  select u.user_id, u.user_name, r.role_id, r.role_name
  from user_table u join role_table r on u.role_id = r.role_id
  where u.id=#{id}
select>

关键配置

  • association:指定关联对象的属性名(property)和类型(javaType)。
  • 关联查询的 SQL 需通过 JOIN 语句获取关联表数据,列名需唯一(可通过表别名区分)。

3.2 一对多关联:用户与订单映射

假设用户表与订单表(order_table)是一对多关系:

<resultMap id="userWithOrdersMap" type="com.example.User">
  <id property="id" column="user_id"/>
  <result property="userName" column="user_name"/>
  
  <collection property="orders" ofType="com.example.Order">
    <id property="orderId" column="order_id"/>
    <result property="orderTime" column="order_time"/>
    <result property="amount" column="order_amount"/>
  collection>
resultMap>

<select id="getUserWithOrders" resultMap="userWithOrdersMap">
  select u.user_id, u.user_name, o.order_id, o.order_time, o.order_amount
  from user_table u left join order_table o on u.id = o.user_id
  where u.id=#{id}
select>

关键配置

  • collection:指定关联集合的属性名(property)和元素类型(ofType)。
  • 一对多关联建议使用左连接(LEFT JOIN),避免主表数据丢失。

4. 实战部分 resultMap 的使用

  1. 复用配置:通过 extends 继承基础 resultMap

<resultMap id="baseUserMap" type="User">
  <id property="id" column="user_id"/>
  <result property="userName" column="user_name"/>
resultMap>


<resultMap id="userWithDetailMap" type="User" extends="baseUserMap">
  <result property="email" column="user_email"/>
  <result property="phone" column="user_phone"/>
resultMap>
  1. 性能优化:使用 autoMapping 减少冗余配置
    MyBatis 支持 autoMapping 属性控制自动映射行为:
<resultMap id="userMap" type="User" autoMapping="true">
  
  <id property="id" column="user_id"/>
resultMap>

以上就是这篇博客的全部内容,下一篇我们将继续探索MyBatis的更多精彩内容。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的MyBatis实战指南知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12969707.html?spm=1001.2014.3001.5482

非常感谢您的阅读,喜欢的话记得三连哦

在这里插入图片描述

你可能感兴趣的:(#,MyBatis实战指南,mybatis,sql,数据库,java)