MyBatis结果映射(ResultMap)的使用

 更新时间:2024年09月25日 08:56:04   作者:Flying_Fish_Xuan  
在MyBatis中,结果映射是实现数据库结果集到Java对象映射的核心,它不仅支持简单的字段映射,还能处理字段名不一致、嵌套对象和集合映射等复杂场景,通过ResultMap,开发者可以灵活定义映射关系,以适应各种需求,感兴趣的可以了解一下

在 MyBatis 中,结果映射(ResultMap) 是将数据库查询结果映射到 Java 对象的核心机制。它允许开发者灵活地定义数据库表字段与 Java 对象属性之间的映射关系,特别是当字段和属性名不一致,或者在处理复杂对象(如嵌套对象、集合)时,ResultMap 提供了极大的便利。

1. 基本概念

在默认情况下,如果数据库字段名和 Java 对象的属性名完全一致,MyBatis 可以自动进行映射。但是,当字段名和属性名不一致时,或者涉及复杂的对象结构时,需要使用 ResultMap 来进行精确的映射。

1.1 基本示例

假设有一个简单的数据库表 users,结构如下:

CREATE TABLE users (
    id INT PRIMARY KEY,
    user_name VARCHAR(50),
    email VARCHAR(100)
);

以及一个对应的 Java 类:

public class User {
    private int id;
    private String username;
    private String email;
    // getters and setters
}

在 SQL 查询中,表的字段 user_name 和 Java 对象的 username 不匹配。这种情况下,可以通过 ResultMap 来手动指定映射关系:

<resultMap id="userResultMap" type="com.example.model.User">
    <id column="id" property="id" />
    <result column="user_name" property="username" />
    <result column="email" property="email" />
</resultMap>

在这里:

  • <id> 标签用于指定主键字段映射到 Java 对象的 id 属性。
  • <result> 标签用于定义普通字段的映射关系。

定义好 ResultMap 之后,可以在 SQL 查询中引用它:

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

通过这种方式,MyBatis 会将数据库查询结果自动映射到 User 对象,即使数据库字段与 Java 属性名不匹配。

2. 字段映射类型

ResultMap 支持多种字段映射类型,以应对不同的数据库字段与 Java 属性的映射需求。

2.1 ID 映射

<id> 标签用于指定数据库表的主键字段,与 Java 对象中的主键属性映射。例如:

<id column="id" property="id" />

这将数据库表中的 id 字段映射到 Java 对象的 id 属性。

2.2 常规字段映射

<result> 标签用于映射非主键字段。例如,将 user_name 映射到 username

<result column="user_name" property="username" />

2.3 嵌套对象映射

ResultMap 支持将查询结果中的某些字段映射到 Java 对象的嵌套对象中。例如,如果 User 类包含一个 Address 对象,可以这样映射:

public class User {
    private int id;
    private String username;
    private String email;
    private Address address;
    // getters and setters
}

public class Address {
    private String street;
    private String city;
    // getters and setters
}

假设 users 表中有以下字段:

  • street:街道名称
  • city:城市名称

可以通过 ResultMap 将这些字段映射到 User 对象中的 Address 属性:

<resultMap id="userResultMap" type="com.example.model.User">
    <id column="id" property="id" />
    <result column="user_name" property="username" />
    <result column="email" property="email" />
    <association property="address" javaType="com.example.model.Address">
        <result column="street" property="street" />
        <result column="city" property="city" />
    </association>
</resultMap>

这里使用 <association> 标签将 Address 类的字段与查询结果中的 street 和 city 进行映射。

2.4 集合映射

对于一对多的关系,MyBatis 提供了 <collection> 标签来处理集合映射。假设一个 User 拥有多个 Order,可以使用 <collection> 进行映射:

public class User {
    private int id;
    private String username;
    private List<Order> orders;
    // getters and setters
}

public class Order {
    private int id;
    private String orderNumber;
    // getters and setters
}

假设 orders 表与 users 表通过 user_id 关联,可以使用以下 ResultMap

<resultMap id="userResultMap" type="com.example.model.User">
    <id column="id" property="id" />
    <result column="user_name" property="username" />
    <collection property="orders" ofType="com.example.model.Order">
        <id column="order_id" property="id" />
        <result column="order_number" property="orderNumber" />
    </collection>
</resultMap>

这里的 <collection> 标签用于处理一对多关系,orders 列表中的每个 Order 对象都由查询结果中的 order_id 和 order_number 进行填充。

3. 复杂映射:多对一与一对多

3.1 多对一映射

多对一关系通常通过 <association> 标签来处理。例如,Order 类中包含一个 User 对象:

public class Order {
    private int id;
    private String orderNumber;
    private User user;
    // getters and setters
}

可以通过以下 ResultMap 将 Order 和 User 的关联关系映射:

<resultMap id="orderResultMap" type="com.example.model.Order">
    <id column="order_id" property="id" />
    <result column="order_number" property="orderNumber" />
    <association property="user" javaType="com.example.model.User">
        <id column="user_id" property="id" />
        <result column="user_name" property="username" />
        <result column="email" property="email" />
    </association>
</resultMap>

在这里,<association> 用于将查询结果中的 user_iduser_name 和 email 字段映射到 Order 对象中的 User 属性。

3.2 一对多映射

一对多关系通常通过 <collection> 标签来处理。假设 User 类中包含多个 Order,每个用户可能有多个订单,可以这样配置:

<resultMap id="userResultMap" type="com.example.model.User">
    <id column="id" property="id" />
    <result column="user_name" property="username" />
    <collection property="orders" ofType="com.example.model.Order">
        <id column="order_id" property="id" />
        <result column="order_number" property="orderNumber" />
    </collection>
</resultMap>

在执行查询时,MyBatis 会将每个用户的订单列表自动映射到 User 对象中的 orders 集合中。

4. 嵌套查询

有时,由于性能问题,或者数据结构过于复杂,直接使用嵌套结果映射可能并不合适。MyBatis 提供了嵌套查询功能,允许在处理复杂对象时,通过子查询获取关联对象的数据。

嵌套查询示例

假设我们有以下结构,Order 类中包含 User 对象,可以使用嵌套查询:

<resultMap id="orderResultMap" type="com.example.model.Order">
    <id column="order_id" property="id" />
    <result column="order_number" property="orderNumber" />
    <association property="user" javaType="com.example.model.User"
                 select="findUserById" column="user_id" />
</resultMap>

<select id="findUserById" resultType="com.example.model.User">
    SELECT id, user_name, email FROM users WHERE id = #{id}
</select>

在这个例子中,<association> 标签中的 select 属性用于指定一个单独的查询来获取关联对象(User),而不是直接从主查询中获取。

5. 自定义类型转换

在某些情况下,数据库中的字段类型可能与 Java 对象属性类型不一致。MyBatis 提供了类型处理器(TypeHandler),用于自定义数据库类型与 Java 类型之间的转换。

自定义 TypeHandler 示例

假设数据库中的性别字段是 INT 类型(0 表示男性,`

1表示女性),而 Java 类中的属性为String 类型(“Male""Female”),可以通过自定义 TypeHandler` 实现类型转换:

public class GenderTypeHandler extends BaseTypeHandler<String> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, "Male".equals(parameter) ? 0 : 1);
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        int gender = rs.getInt(columnName);
        return gender == 0 ? "Male" : "Female";
    }

    // 其他重载方法省略
}

在 MyBatis 配置中注册自定义 TypeHandler

<typeHandlers>
    <typeHandler javaType="java.lang.String" jdbcType="INTEGER" handler="com.example.handler.GenderTypeHandler"/>
</typeHandlers>

这样,在处理性别字段时,MyBatis 会自动使用自定义的类型转换逻辑。

结论

MyBatis 的 ResultMap 是一种强大的结果映射机制,允许开发者灵活地将数据库查询结果与 Java 对象进行映射。通过使用 ResultMap,可以处理字段名不一致、嵌套对象、一对多、多对一等复杂映射场景。结合自定义类型转换和嵌套查询,MyBatis 提供了高度灵活的持久化解决方案,能够满足复杂的数据映射需求。

到此这篇关于MyBatis结果映射(ResultMap)的使用的文章就介绍到这了,更多相关MyBatis结果映射内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • GC算法实现篇之并发标记清除

    GC算法实现篇之并发标记清除

    这篇文章主要为大家介绍了GC算法实现篇之并发-标记-清除, CMS垃圾收集器在减少停顿时间上做了很多给力的工作, 大量的并发线程执行的工作并不需要暂停应用线程
    2022-01-01
  • Spring配置和使用Properties文件的详细步骤

    Spring配置和使用Properties文件的详细步骤

    在Spring框架中,.properties 文件通常用于存储配置信息,如数据库连接、服务地址、应用参数等,本文给大家介绍了Spring配置和使用Properties文件的详细步骤,需要的朋友可以参考下
    2024-05-05
  • jpanel设置背景图片的二个小例子

    jpanel设置背景图片的二个小例子

    这篇文章主要介绍了jpanel设置背景图片的二个小例子,实现了动态加载图片做背景的方法,需要的朋友可以参考下
    2014-03-03
  • java实现去除ArrayList重复字符串

    java实现去除ArrayList重复字符串

    本文主要介绍了java实现去除ArrayList重复字符串,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-09-09
  • jvm oom排查记录剖析

    jvm oom排查记录剖析

    这篇文章主要为大家介绍了jvm oom排查记录剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Java如何实现判断并输出文件大小

    Java如何实现判断并输出文件大小

    这篇文章主要介绍了Java如何实现判断并输出文件大小问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • 解决nacos升级spring cloud 2020.0无法使用bootstrap.yml的问题

    解决nacos升级spring cloud 2020.0无法使用bootstrap.yml的问题

    这篇文章主要介绍了解决nacos升级spring cloud 2020.0无法使用bootstrap.yml的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • JavaWeb pageContext对象原理解析

    JavaWeb pageContext对象原理解析

    这篇文章主要介绍了JavaWeb pageContext对象原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Java基于final修饰数据过程解析

    Java基于final修饰数据过程解析

    这篇文章主要介绍了Java基于final修饰数据过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • java实现归并排序算法

    java实现归并排序算法

    归并排序:是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 本文我们就来详细的探讨下。
    2015-04-04

最新评论