MyBatis 通过 结果映射机制 将 SQL 查询结果转换为目标对象并返回,核心流程与映射形式如下:
️ 一、结果封装流程
-
解析映射规则
- 自动映射:未显式定义
resultMap
时,MyBatis 按列名与对象属性名自动匹配(支持驼峰转换)。 - 显式映射:通过
<resultMap>
手动定义字段与属性的映射关系,可处理复杂场景(如嵌套对象、集合)。
- 自动映射:未显式定义
-
对象实例化
- 调用目标类的无参构造方法,通过反射创建对象实例。
-
属性填充
- 使用
TypeHandler
转换数据库类型到 Java 类型(如日期格式化)。 - 通过反射调用属性的
setter
方法或直接修改字段赋值。 - 嵌套处理:若存在关联对象或集合(如
<association>
、<collection>
),递归执行上述流程封装子对象。
- 使用
📌 二、映射形式
-
resultType
自动映射- 适用场景:列名与属性名完全一致(或驼峰自动转换)。
- 示例:
<select id="selectUser" resultType="com.example.User"> SELECT id, user_name AS userName FROM user </select>
💡 此处
user_name
通过别名userName
匹配对象属性。
-
resultMap
显式映射- 适用场景:字段与属性名不一致、存在嵌套对象、集合或需要特殊类型转换时。
- 关键标签:
<result>
:定义普通字段映射。<id>
:标识主键字段(提升性能)。<association>
:映射单个关联对象(如Order
关联User
)。<collection>
:映射对象集合(如User
包含多个Order
)。
- 示例:
<resultMap id="userMap" type="com.example.User"> <id property="id" column="user_id"/> <result property="name" column="user_name"/> <collection property="orders" ofType="com.example.Order"> <result property="orderId" column="oid"/> </collection> </resultMap>
-
列别名辅助映射
- SQL 查询中为字段设置别名,使其匹配对象属性名(如
SELECT address AS homeAddr
)。
- SQL 查询中为字段设置别名,使其匹配对象属性名(如
🔧 三、底层实现机制
- 核心组件:
Executor
:执行 SQL 语句。ResultSetHandler
:将ResultSet
结果集转换为目标对象。
- 反射优化:
- 首次映射后,MyBatis 缓存映射关系(
ResultMap
),后续查询复用以减少反射开销。
- 首次映射后,MyBatis 缓存映射关系(
⚠️ 注意:若自动映射时存在字段无对应属性,该字段会被忽略;显式映射中未配置的字段则不会赋值。