MyBatis 映射关系入门:一对一、一对多、多对多解析

Mybatis 映射关系 

       在 MyBatis 中,关系的映射主要通过 <association><collection> 标签来处理,分别对应 一对一一对多/ 多对多 关系。

1. 一对一 (One-to-One)

定义
一个实体与另一个实体之间存在唯一的关联关系。例如,一个用户有唯一的身份证信息,一个学生有唯一的档案信息。

数据库设计

  • 使用 两个表,通过主键或唯一键进行关联。
  • 两个表之间的关联通常是主键关联唯一约束

示例:    

表1:user(用户表)

CREATE TABLE user (
    id BIGINT PRIMARY KEY,
    username VARCHAR(50)
);

表2:user_detail(用户详情表)

CREATE TABLE user_detail (
    id BIGINT PRIMARY KEY,
    address VARCHAR(100),
    phone_number VARCHAR(20),
    FOREIGN KEY (id) REFERENCES user(id)
);

关联说明user.iduser_detail.id 是一对一的关系,每个用户只能有一条详细信息。

一对一映射

MyBatis 使用 <association> 标签来映射一对一的关系。

示例:用户与用户详情

  • 表结构

    • user(用户表):id, username
    • user_detail(用户详情表):id, address, phone_number

对应实体类:

public class User {
    private Long id;
    private String username;
    private UserDetail userDetail; // 一对一关系
}

public class UserDetail {
    private Long id;
    private String address;
    private String phoneNumber;
}
 ResultMap 配置
<resultMap id="userWithDetailMap" type="User">
    <id property="id" column="id"/>
    <result property="username" column="username"/>
    <association property="userDetail" javaType="UserDetail">
        <id property="id" column="detail_id"/>
        <result property="address" column="address"/>
        <result property="phoneNumber" column="phone_number"/>
    </association>
</resultMap>

<select id="getUserWithDetail" resultMap="userWithDetailMap">
    SELECT u.id, u.username, d.id AS detail_id, d.address, d.phone_number
    FROM user u
    LEFT JOIN user_detail d ON u.id = d.id
    WHERE u.id = #{userId}
</select>

2. 一对多 (One-to-Many)

定义
一个实体与另一个实体之间存在一对多的关联。例如,一个用户可以有多张订单,一个部门可以有多个员工。

数据库设计

  • 使用 两个表,通过外键关联。
  • 在“多”的一方表中,添加一个外键指向“单”的一方表。

示例

表1:user(用户表)

CREATE TABLE user (
    id BIGINT PRIMARY KEY,
    username VARCHAR(50)
);

 表2:orders(订单表)

CREATE TABLE orders (
    id BIGINT PRIMARY KEY,
    order_number VARCHAR(20),
    user_id BIGINT,
    FOREIGN KEY (user_id) REFERENCES user(id)
);

关联说明user.idorders.user_id 是一对多的关系,每个用户可以有多张订单。

一对多映射

MyBatis 使用 <collection> 标签来映射一对多的关系。

示例:用户与订单

  • 表结构

    • user(用户表):id, username
    • orders(订单表):id, order_number, user_id

对应实体类

public class User {
    private Long id;
    private String username;
    private List<Order> orders; // 一对多关系
}

public class Order {
    private Long id;
    private String orderNumber;
}
 ResultMap 配置
<resultMap id="userWithOrdersMap" type="User">
    <id property="id" column="user_id"/>
    <result property="username" column="username"/>
    <collection property="orders" ofType="Order">
        <id property="id" column="order_id"/>
        <result property="orderNumber" column="order_number"/>
    </collection>
</resultMap>

<select id="getUserWithOrders" resultMap="userWithOrdersMap">
    SELECT u.id AS user_id, u.username, o.id AS order_id, o.order_number
    FROM user u
    LEFT JOIN orders o ON u.id = o.user_id
    WHERE u.id = #{userId}
</select>

3. 多对多 (Many-to-Many)

定义
两个实体之间存在多对多的关联。例如,一个学生可以选修多门课程,一门课程也可以有多个学生选修。

数据库设计

  • 使用 三个表,通过中间表来建立关联。
  • 中间表通常包含两个外键,分别指向关联的两个表。

示例

表1:student(学生表)

CREATE TABLE student (
    id BIGINT PRIMARY KEY,
    name VARCHAR(50)
);

表2:course(课程表)

CREATE TABLE course (
    id BIGINT PRIMARY KEY,
    course_name VARCHAR(50)
);

表3中间表:student_course(学生课程关联表) 

CREATE TABLE student_course (
    student_id BIGINT,
    course_id BIGINT,
    PRIMARY KEY (student_id, course_id),
    FOREIGN KEY (student_id) REFERENCES student(id),
    FOREIGN KEY (course_id) REFERENCES course(id)
);

关联说明studentcourse 通过 student_course 中间表建立多对多的关联,一个学生可以选修多门课程,一门课程也可以有多个学生。

多对多映射

MyBatis 使用 <collection> 标签来映射多对多的关系,通过中间表进行关联。

示例:学生与课程

  • 表结构

    • student(学生表):id, name
    • course(课程表):id, course_name
    • student_course(中间表):student_id, course_id

对应实体类

public class Student {
    private Long id;
    private String name;
    private List<Course> courses; // 多对多关系
}

public class Course {
    private Long id;
    private String courseName;
}
 ResultMap 配置
<resultMap id="studentWithCoursesMap" type="Student">
    <id property="id" column="student_id"/>
    <result property="name" column="name"/>
    <collection property="courses" ofType="Course">
        <id property="id" column="course_id"/>
        <result property="courseName" column="course_name"/>
    </collection>
</resultMap>

<select id="getStudentWithCourses" resultMap="studentWithCoursesMap">
    SELECT s.id AS student_id, s.name, c.id AS course_id, c.course_name
    FROM student s
    LEFT JOIN student_course sc ON s.id = sc.student_id
    LEFT JOIN course c ON sc.course_id = c.id
    WHERE s.id = #{studentId}
</select>

4:区别总结

类型定义数据库设计举例
一对一一个实体与另一个实体唯一关联两个表,主键或唯一键关联用户与用户详情
一对多一个实体与多个实体关联两个表,使用外键关联用户与订单,部门与员工
多对多多个实体之间互相关联三个表,通过中间表建立关联学生与课程,用户与角色

选择关系类型的依据
  1. 一对一:当两个表中的数据一一对应且每个记录仅能有一个关联记录时,使用一对一。例如用户与其身份证信息。
  2. 一对多:当一个表的记录可以对应另一个表中的多个记录时,使用一对多。例如用户与订单、部门与员工。
  3. 多对多:当两个表中的记录互相可以有多个关联时,使用多对多。例如学生与课程、用户与角色。
实例化理解
  • 一对一用户:张三 -> 身份证信息:3701XXXXXXXXXXXX

  • 一对多用户:张三 -> 订单:#1001, #1002, #1003

  • 多对多学生:张三 -> 课程:数学, 英语 课程:数学 -> 学生:张三, 李四

 5:Mybatis映射区别

关系类型MyBatis 标签描述示例
一对一<association>一个实体与另一个实体唯一关联用户与用户详情
一对多<collection>一个实体与多个实体关联用户与订单、部门与员工
多对多<collection>通过中间表关联多个实体学生与课程、用户与角色
  • 一对一使用 <association>,因为关联的对象是一个单一的实体。
  • 一对多和多对多使用 <collection>,因为关联的对象是一个集合。
  • 多对多需要通过中间表进行关联,这与一对多的区别在于 SQL 中的表连接复杂度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大怪~将军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值