在MyBatis中,resultMap
是一种高级映射策略,它允许你详细地指定如何从数据库结果集中映射数据到Java对象。通过resultMap
,你可以定制列名和对象属性名之间的映射关系、处理复杂类型的映射等。另一方面,autoMapping
是一个方便的特性,它允许MyBatis自动映射数据库列到同名的Java对象属性,无需显式指定每个字段的映射。
当resultMap
和autoMapping
同时使用时,MyBatis如何处理两者之间的冲突?理解这一点需要深入MyBatis的映射处理机制。以下是基于MyBatis源码的分析,注意这一分析基于特定的MyBatis版本,不同版本的实现细节可能会有所不同。
结合源码解析
映射处理流程
-
解析
resultMap
配置 :在解析XML映射文件时,MyBatis首先解析<resultMap>
元素,构建一个ResultMap
对象,它包含了映射的所有信息。这包括映射的列名、Java属性名、数据类型等。 -
处理自动映射(
autoMapping
) :在执行查询并处理结果集时,如果启用了autoMapping
,MyBatis会尝试自动映射那些在resultMap
中未明确指定的列。autoMapping
的处理发生在显式映射(通过resultMap
定义的映射)之后。
冲突处理
如果resultMap
中显式指定了某个字段的映射,同时该字段也符合自动映射的条件(即数据库列名和Java对象属性名相同),MyBatis将遵循以下原则处理冲突:
- 显式映射优先 :
resultMap
中的映射配置具有更高的优先级。MyBatis会使用resultMap
中定义的映射信息,而不是自动映射的结果。这意味着,即使autoMapping
尝试映射同一个字段,resultMap
中的配置将覆盖它。
代码演示
假设我们有以下resultMap
和查询方法的配置:
xml
<resultMap id="exampleMap" type="Example">
<result property="name" column="name_column"/>
</resultMap>
<select id="selectExample" resultMap="exampleMap">
SELECT name_column, description FROM example_table
</select>
在这个例子中,即使类Example
有一个名为description
的属性,且表example_table
中也有一个同名的列,description
的映射仍然会依赖于autoMapping
的行为,除非在resultMap
中也为description
提供了显式映射。
深入细节
-
源码位置 :
DefaultResultSetHandler
类是处理结果集和映射逻辑的核心。在这个类中,applyAutomaticMappings()
方法处理自动映射逻辑,而applyPropertyMappings()
方法处理resultMap
中定义的显式映射。 -
autoMapping
的开关 :可以在MyBatis配置文件中全局设置autoMappingBehavior
,或者在resultMap
中通过autoMapping
属性为单独的映射开启或关闭自动映射。
综上所述,MyBatis在处理resultMap
和autoMapping
冲突时,会优先考虑resultMap
中的显式映射配置。这一设计保证了映射的确定性和可预测性,允许开发者在需要的时候通过resultMap
提供精确控制,同时又能在简单场景下利用autoMapping
简化配置。