mybatis中resultMap的association及collectio的使用详解

2025-07-23 20:50

本文主要是介绍mybatis中resultMap的association及collectio的使用详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《mybatis中resultMap的association及collectio的使用详解》MyBatis的resultMap定义数据库结果到Java对象的映射规则,包含id、type等属性,子元素需...

1.reusltmap的说明

resultmap定义了数据库的结果映射到Java对象的规则,resultmap包含4个属性:

  • id: ResultMap 的唯一标识
  • type: 映射到的 Java 类型(全限定类名或别名)
  • extends: 继承另一个 ResultMap
  • autoMapping: 是否开启自动映射(true/false)

前三个比较常用

resultmap包含以下子元素,并且子元素是有定义顺序的,如下:

  • <constructor> (可选)
  • <id> (至少一个)
  • <result> (零个或多个)
  • <association> (零个或多个)
  • <collection> (零个或多个)
  • <discriminator> (可选)

必须遵循上述顺序,如果顺序不正确,MyBATis 在解析 XML 时会抛出异常

  • <id> 元素必须出现在 <result> 元素之前
  • 如果使用 <constructor>,它必须是第一个元素
  • <discriminator> 必须是最后一个元素(如果存在)

2.association的使用

<association> 是 MyBatis 中用于处理一对一关联关系的元素,它可以将查询结果中的一部分数据映射到一个复杂的关联对象中。

在实际开发中,如果想一次查询两张表的数据,不想通过两次查询的方式,而是想一次查询出来,可以通过两张表关联将表A和表B的数据都查询出来

属性名说明
propertyJava对象中的属性名
javaType关联对象的Java类型(全限定类名或别名)
resultMap引用外部定义的resultMap
column传递给嵌套查询的列名(可以是多个列:column="{prop1=col1,prop2=col2}")
select另一个映射语句的ID,用于嵌套查询
fetchType覆盖全局的延迟加载设置(lazy/eager)
autoMapping是否启用自动映射(true/false)
<!-- 一对一关联映射示例 -->
<resultMap id="UserWithDeptMap" type="com.example.User">
    <!-- 用户表字段映射 -->
    <id column="user_id" property="id" jdbcType="BIGINT"/>
    <result column="user_name" property="name" jdbcType="VARCHAR"/>
    <result column="user_age" property="age" jdbcType="INTEGER"/>

    <!-- 一对一关联 department 对象 -->
    <association property="departmpythonent" javaType="com.example.Department">
        <id column="dept_id" property="id" jdbcType="BIGINT"/>
        <result column="dept_name" property="deptName" jdbcType="VARCHAR"/>
        <result column="dept_location" property="location" jdbcType="VARCHAR"/>
    </association>
</resultMap>
<select id="selectUserWithDepartment" resultMap="UserWithDeptMap">
    SELECT 
        u.id          AS user_id,
        u.name        AS user_name,
        u.age         AS user_age,
        d.id          AS dept_id,
        d.name        AS dept_name,
        d.location    AS dept_location
    FROM 
        user u
    LEFT JOIN 
        department d ON u.dept_id = d.id
    WHERE 
        u.id = #{userId}
</select>
package com.example;

public class User {
    private Long id;          // 对应 user编程_id 字段
    private String name;      // 对应 user_name 字段
    private Integer age;      // 对应 user_age 字段
    private Department department; // 一对一关联对象

    // 必须的 getter 和 setter 方法
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }
}
package com.example;

public class Department {
    private Long id;          // 对应 dept_id 字段
    private String deptName;  // 对应 dept_name 字段
    private String location;  // 对应 dept_location 字段

    // 必须的 getter 和 setter 方法
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
   China编程     this.id = id;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }
}

使用关联查询只需要指定以下两个属性即可 

配置项

作用

property="department"

指定 User 类中关联属性的名称(需与字段名一致)。

javaType

指定关联对象的完整类名(可省略,MyBatis 通常能自动推断)。

3.collection的使用

<collection> 是 MyBatis 中用于处理一对多关联关系的核心元素,它能够将查询结果中的多条记录映射到一个集合属性中(如 List、Set 等)

属性名是否必填说明
property必填Java对象中的集合属性名称
ofType条件必填集合中元素的Java类型(当不使用resultMap时必填)
column条件必填传递给嵌套查询的列名(使用select时必填)
select可选另一个映射语句的ID,用于嵌套查询
fetchType可选加载方式(lazy/eager),覆盖全局配置
javaType可选集合的Java类型(如ArrayList、HashSet等)
resultMap可选引用外部定义的resultMap
autoMapping可选是否启用自动映射(true/false)
<resultMap id="UserWithOrdersMap" type="com.example.model.User">
    <id property="id" column="user_id"/>
    <result property="name" column="user_name"/>
    <result property="age" column="user_age"/>
    
    <!-- 一对多关联订单集合 -->
    <collection property="orders" ofType="com.example.model.Order">
        <id property="id" column="order_id"/>
        <result property="orderNo" column="order_no"/>
        <result property="amount" column="order_amount"/>
        <result property="userId" column="user_id"/>
    </collection>
</resultMap>

<select id="selectUserWithOrders" resultMap="UserWithOrdersMap">
    SELECT 
        u.id as user_id,
        u.name as user_name,
        u.age as user_age,
        o.id as order_id,
        o.order_no as order_no,
        o.amount as order_amount,
        o.user_id
    FROM user u
    LEFT JOIN orders o ON u.id = o.user_id
    WHERE u.id = #{userId}
</select>
package com.example.model;

import java.util.List;

public class User {
    private Long id;
    private String name;
    private Integer age;
    private List<Order> orders; // 一对多关联的订单集合

    // getters and setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public vChina编程oid setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public List<Order> getOrders() {
        return orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }
}
package com.example.model;

public class Order {
    private Long id;
    private String orderNo;
    private Double amount;
    private Long userId; // 外键,关联用户ID

    // getters and setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public Double getAmount() {
        return amount;
    }

    public void setAmount(Double amount) {
        this.amount = amount;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }
}

使用关联查询只需要指定以下两个属性即可 

属性名是否必填说明
property必填Java对象中的集合属性名称
ofType条件必填集合中元素的Java类型(当不使用resultMap时必填)

4.总结

①在 MyBatis 的 <resultMap> 中,如果使用 <association> 或 <collection> 映射关联关系,必须为父对象(主对象)至少定义一个 <id> 属性

MyBatis 使用 <id> 来唯一标识一个对象,用于:

  • 一级/二级缓存的键值
  • 解决嵌套映射中的循环引用问题
  • 避免重复创建相同对象(性能优化

关联映射的依赖

  • 当存在 <association> 或 <collection> 时编程China编程,MyBatis 需要通过父对象的 <id> 来管理关联对象的加载和绑定。

②association及collection中的id属性是可选的,但建议加上,它用于避免重复子对象(例如 JOIN 导致重复数据时去重)。

如果子对象中定义了 <id> 属性,MyBatis 会对 <collection> 中的重复子对象进行去重。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持China编程(www.chinasem.cn)。

这篇关于mybatis中resultMap的association及collectio的使用详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155462

相关文章

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

Java Spring的依赖注入理解及@Autowired用法示例详解

《JavaSpring的依赖注入理解及@Autowired用法示例详解》文章介绍了Spring依赖注入(DI)的概念、三种实现方式(构造器、Setter、字段注入),区分了@Autowired(注入... 目录一、什么是依赖注入(DI)?1. 定义2. 举个例子二、依赖注入的几种方式1. 构造器注入(Con

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束

详解MySQL中JSON数据类型用法及与传统JSON字符串对比

《详解MySQL中JSON数据类型用法及与传统JSON字符串对比》MySQL从5.7版本开始引入了JSON数据类型,专门用于存储JSON格式的数据,本文将为大家简单介绍一下MySQL中JSON数据类型... 目录前言基本用法jsON数据类型 vs 传统JSON字符串1. 存储方式2. 查询方式对比3. 索引

Apache Ignite缓存基本操作实例详解

《ApacheIgnite缓存基本操作实例详解》文章介绍了ApacheIgnite中IgniteCache的基本操作,涵盖缓存获取、动态创建、销毁、原子及条件更新、异步执行,强调线程池注意事项,避免... 目录一、获取缓存实例(Getting an Instance of a Cache)示例代码:二、动态

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be

Java中使用 @Builder 注解的简单示例

《Java中使用@Builder注解的简单示例》@Builder简化构建但存在复杂性,需配合其他注解,导致可变性、抽象类型处理难题,链式编程非最佳实践,适合长期对象,避免与@Data混用,改用@G... 目录一、案例二、不足之处大多数同学使用 @Builder 无非就是为了链式编程,然而 @Builder

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

Linux之platform平台设备驱动详解

《Linux之platform平台设备驱动详解》Linux设备驱动模型中,Platform总线作为虚拟总线统一管理无物理总线依赖的嵌入式设备,通过platform_driver和platform_de... 目录platform驱动注册platform设备注册设备树Platform驱动和设备的关系总结在 l

mybatis-plus QueryWrapper中or,and的使用及说明

《mybatis-plusQueryWrapper中or,and的使用及说明》使用MyBatisPlusQueryWrapper时,因同时添加角色权限固定条件和多字段模糊查询导致数据异常展示,排查发... 目录QueryWrapper中or,and使用列表中还要同时模糊查询多个字段经过排查这就导致只要whe