个人疑惑点(一):mapper.xml 文件里的 SQL 语句在什么场景下需要用到 resultMap

在 MyBatis 框架中,mapper.xml 文件里的 SQL 语句在以下几种常见场景下需要用到 resultMap

1. 结果集字段与实体类属性名称不匹配

当 SQL 查询结果集中的列名和要映射的 Java 实体类的属性名不一致时,需要 resultMap 来指定映射关系。例如,数据库表中的列名为 user_name,但 Java 实体类 User 中的属性名为 userName,此时可以通过 resultMap 来建立正确的映射,此种情况也可以在配置文件中开启驼峰映射解决,示例如下:

xml

bash 复制代码
<resultMap id="userResultMap" type="com.example.domain.User">
    <result property="userName" column="user_name"/>
</resultMap>

<select id="getUserById" resultMap="userResultMap">
    SELECT user_name FROM users WHERE id = #{id}
</select>

通过 resultMapproperty 指定实体类属性,column 指定查询结果集中的列名,从而让 MyBatis 能够正确地将查询结果赋值给实体类的属性。

2. 处理复杂的嵌套结果(一对一、一对多关系)

  • 一对一关系 :当查询结果涉及到关联表的一对一关系,且需要将关联数据映射到一个包含子对象的实体类中时,可使用 resultMap 进行嵌套结果映射。比如,查询用户及其关联的部门信息,User 实体类中有一个 Department 类型的属性。

xml

xml 复制代码
<resultMap id="userWithDeptResultMap" type="com.example.domain.User">
    <id property="id" column="user_id"/>
    <result property="userName" column="user_name"/>
    <!-- 嵌套结果映射处理一对一关系 -->
    <association property="department" javaType="com.example.domain.Department">
        <id property="id" column="dept_id"/>
        <result property="deptName" column="dept_name"/>
    </association>
</resultMap>

<select id="getUserWithDeptById" resultMap="userWithDeptResultMap">
    SELECT 
        u.user_id, u.user_name, d.dept_id, d.dept_name
    FROM 
        users u
    LEFT JOIN 
        departments d ON u.dept_id = d.dept_id
    WHERE 
        u.user_id = #{id}
</select>
  • 一对多关系 :如果查询结果涉及到一对多的关系,比如查询部门及其包含的所有用户,Department 实体类中有一个 List<User> 类型的属性来存储该部门的用户列表。

xml

xml 复制代码
<resultMap id="deptWithUsersResultMap" type="com.example.domain.Department">
    <id property="id" column="dept_id"/>
    <result property="deptName" column="dept_name"/>
    <!-- 嵌套结果映射处理一对多关系 -->
    <collection property="userList" ofType="com.example.domain.User">
        <id property="id" column="user_id"/>
        <result property="userName" column="user_name"/>
    </collection>
</resultMap>

<select id="getDeptWithUsersById" resultMap="deptWithUsersResultMap">
    SELECT 
        d.dept_id, d.dept_name, u.user_id, u.user_name
    FROM 
        departments d
    LEFT JOIN 
        users u ON d.dept_id = u.dept_id
    WHERE 
        d.dept_id = #{id}
</select>

3. 复用映射规则

当多个 SQL 查询需要使用相同的结果映射逻辑时,可以定义一个 resultMap 并在多个 select 标签中复用,这样可以提高代码的复用性和可维护性。例如,有多个查询都需要将用户信息映射到 User 实体类,且映射规则一致,就可以将映射规则定义在一个 resultMap 中,然后在不同的 select 语句中通过 resultMap 属性引用。

xml

sql 复制代码
<resultMap id="commonUserResultMap" type="com.example.domain.User">
    <id property="id" column="user_id"/>
    <result property="userName" column="user_name"/>
    <result property="email" column="user_email"/>
</resultMap>

<select id="getUserById" resultMap="commonUserResultMap">
    SELECT user_id, user_name, user_email FROM users WHERE id = #{id}
</select>

<select id="getAllUsers" resultMap="commonUserResultMap">
    SELECT user_id, user_name, user_email FROM users
</select>

4. 对查询结果进行类型转换或特殊处理

如果查询结果集中某个字段的数据类型需要转换为与实体类属性不同的类型,或者需要对结果进行一些特殊处理(比如日期格式化等),可以在 resultMap 中通过自定义的 typeHandler 来实现。例如,数据库中存储的日期是时间戳格式,而实体类中对应的属性是 java.util.Date 类型,就可以配置 typeHandler 进行转换。

xml

ini 复制代码
<resultMap id="userWithDateResultMap" type="com.example.domain.User">
    <id property="id" column="user_id"/>
    <result property="userName" column="user_name"/>
    <result property="createTime" column="create_time" typeHandler="com.example.handler.TimestampToDateTypeHandler"/>
</resultMap>

<select id="getUserWithCreateTime" resultMap="userWithDateResultMap">
    SELECT user_id, user_name, create_time FROM users WHERE id = #{id}
</select>

总之,resultMap 提供了一种灵活强大的方式来控制 SQL 查询结果到 Java 实体类的映射过程,在面对复杂映射需求时能发挥重要作用。

相关推荐
小鹅叻1 天前
MyBatis题
java·tomcat·mybatis
小猪咪piggy1 天前
【JavaEE】(18) MyBatis 进阶
java·java-ee·mybatis
计算机学姐1 天前
基于SpringBoot的老年人健康数据远程监控管理系统【2026最新】
java·vue.js·spring boot·后端·mysql·spring·mybatis
一叶飘零_sweeeet2 天前
如何避免MyBatis二级缓存中的脏读
java·redis·mybatis
chen_note2 天前
Redis数据持久化——RDB快照和Aof日志追加
java·数据库·mybatis·持久化·aof·rdb
yvya_2 天前
Mybatis总结
java·spring·mybatis
计算机学姐3 天前
基于SpringBoot的社团管理系统【2026最新】
java·vue.js·spring boot·后端·mysql·spring·mybatis
没有bug.的程序员3 天前
MyBatis 初识:框架定位与核心原理——SQL 自由掌控的艺术
java·数据库·sql·mybatis
一叶飘零_sweeeet3 天前
在分布式环境下正确使用MyBatis二级缓存
java·分布式·mybatis