当前位置: 代码网 > it编程>编程语言>Java > mybatis中resultMap的association及collectio的使用详解

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

2025年07月23日 Java 我要评论
1.reusltmap的说明resultmap定义了数据库的结果映射到java对象的规则,resultmap包含4个属性:id: resultmap 的唯一标识type: 映射到的 java 类型(全

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="department" 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) {
        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 void 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> 时,mybatis 需要通过父对象的 <id> 来管理关联对象的加载和绑定。

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

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com