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结果映射内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot自动配置深入探究实现原理

    SpringBoot自动配置深入探究实现原理

    在springboot的启动类中可以看到@SpringBootApplication注解,它是SpringBoot的核心注解,也是一个组合注解。其中@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解尤为重要。今天我们就来浅析这三个注解的含义
    2022-08-08
  • Springboot 接口对接文件及对象的操作方法

    Springboot 接口对接文件及对象的操作方法

    这篇文章主要介绍了Springboot 接口对接文件及对象的操作,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • 深入Java不可变类型的详解

    深入Java不可变类型的详解

    本篇文章是Java中的不可变类型进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • C++ 程序流程结构详解

    C++ 程序流程结构详解

    这篇文章主要介绍了C++程序的程序流程结构以及关系和逻辑运算符讲解,是C++入门学习中的基础知识,需要的朋友可以参考下
    2021-09-09
  • java伪泛型知识点详解

    java伪泛型知识点详解

    在本篇文章里小编给大家整理的是一篇关于java伪泛型知识点详解内容,有需要的朋友们可以跟着学习参考下。
    2021-06-06
  • 详谈异步log4j2中的location信息打印问题

    详谈异步log4j2中的location信息打印问题

    这篇文章主要介绍了详谈异步log4j2中的location信息打印问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • JAVA实现SOCKET多客户端通信的案例

    JAVA实现SOCKET多客户端通信的案例

    这篇文章主要介绍了JAVA实现SOCKET多客户端通信的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Java序列化和反序列化示例介绍

    Java序列化和反序列化示例介绍

    大家好,本篇文章主要讲的是Java序列化和反序列化示例介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01
  • Java中Scanner用法实例解析

    Java中Scanner用法实例解析

    Scanner 指的是java.util包下的Scanner类,可以接收控制台输入的数据,下面这篇文章主要给大家介绍了关于Java中Scanner用法实例的相关资料,文中通过实例代码以及图文介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • java JVM原理与常识知识点

    java JVM原理与常识知识点

    在本文中小编给大家分享的是关于java的JVM原理和java常识,有兴趣的朋友们可以学习下
    2018-12-12

最新评论