如您在前面的部分已经看到的那样,对于简单的情况,MyBatis可以自动为您进行结果映射,而在其他情况下,您需要构建一个结果映射。但正如您将在本节中看到的那样,您也可以混合使用这两种策略。让我们深入了解自动映射是如何工作的。
在自动映射结果时,MyBatis会获取列名并查找具有相同名称(不区分大小写)的属性。这意味着如果找到一个名为ID的列和一个名为id的属性,MyBatis将使用ID列的值设置id属性。
通常情况下,数据库列使用大写字母和下划线命名,而Java属性通常遵循驼峰命名约定。为了在它们之间启用自动映射,请将设置mapUnderscoreToCamelCase设置为true。
自动映射即使在存在特定的结果映射时也可以工作。当发生这种情况时,对于每个结果映射,在ResultSet中出现的所有未进行手动映射的列将被自动映射,然后再处理手动映射。在下面的示例中,id和userName列将被自动映射,而hashed_password列将被手动映射。
<select id="selectUsers" resultMap="userResultMap">
select
user_id as "id",
user_name as "userName",
hashed_password
from some_table
where id = #{id}
</select>
<resultMap id="userResultMap" type="User">
<result property="password" column="hashed_password"/>
</resultMap>
有三个自动映射级别:
- NONE - 禁用自动映射。只会设置手动映射的属性。
- PARTIAL - 除了内部定义了嵌套结果映射的结果(联接)之外,其他都会自动映射。
- FULL - 自动映射所有内容。
默认值是PARTIAL,这是有原因的。当使用FULL时,自动映射将在处理连接结果时执行,而连接会在同一行中检索多个不同实体的数据,因此可能会导致不期望的映射。为了理解风险,请参考以下示例:
<select id="selectBlog" resultMap="blogResult">
select
B.id,
B.title,
A.username,
from Blog B left outer join Author A on B.author_id = A.id
where B.id = #{id}
</select>
<resultMap id="blogResult" type="Blog">
<association property="author" resultMap="authorResult"/>
</resultMap>
<resultMap id="authorResult" type="Author">
<result property="username" column="author_username"/>
</resultMap>
使用这个结果映射,Blog和Author都会被自动映射。但请注意,Author有一个id属性,并且ResultSet中有一个名为id的列,所以Author的id将被填充为Blog的id,这不是你所期望的结果。因此,在使用FULL选项时要谨慎。
不论配置了哪个自动映射级别,您都可以通过在特定的ResultMap中添加属性autoMapping来启用或禁用自动映射:
<resultMap id="userResultMap" type="User" autoMapping="false">
<result property="password" column="hashed_password"/>
</resultMap>