当前位置: 首页 > article >正文

MyBatis 关联映射详解

目录

一、创建表结构

1. 学生表 (student)

2. 教师表 (teacher)

二、一对一 & 多对一 关系映射

1. 连表查询(直接查询)

2. 分步查询(懒加载)

三、一对多 关系映射

1. 直接查询

2. 分步查询

四、MyBatis 延迟加载(懒加载)

1. 配置全局懒加载

2. 配置分步查询的懒加载

3. 测试代码

4. 强制立即加载(eager)


一、创建表结构

在 MyBatis 进行关联映射时,我们需要创建 student(学生表)和 teacher(教师表),并建立它们之间的关联。

1. 学生表 (student)

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `Sname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `t_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

INSERT INTO `student` VALUES (1, '张三', '男', 18, 1);
INSERT INTO `student` VALUES (2, '李四', '女', 18, 1);
...

SET FOREIGN_KEY_CHECKS = 1;

2. 教师表 (teacher)

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `Tname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

INSERT INTO `teacher` VALUES (1, '张老师');
INSERT INTO `teacher` VALUES (2, '李老师');

SET FOREIGN_KEY_CHECKS = 1;

二、一对一 & 多对一 关系映射

1. 连表查询(直接查询)

实体类
public class Student {
    private Integer id;
    private String Sname;
    private String sex;
    private Integer age;
    private Integer t_id;
    private Teacher teacher; // 关联的教师对象
}

public class Teacher {
    private Integer id;
    private String Tname;
}
查询语句
<select id="getStudent1" resultMap="StudentTeacher1">
    SELECT student.id, student.Sname, teacher.Tname
    FROM student
    LEFT JOIN teacher ON student.t_id = teacher.id
</select>

<resultMap id="StudentTeacher1" type="com.qcby.entity.Student">
    <result property="id" column="id"/>
    <result property="Sname" column="Sname"/>
    <association property="teacher" javaType="com.qcby.entity.Teacher">
        <result property="id" column="id"/>
        <result property="Tname" column="Tname"/>
    </association>
</resultMap>

2. 分步查询(懒加载)

<select id="getStudent" resultMap="StudentTeacher">
    SELECT * FROM student;
</select>

<resultMap id="StudentTeacher" type="com.qcby.entity.Student">
    <association property="teacher" column="t_id" javaType="com.qcby.entity.Teacher" select="getTeacher"/>
</resultMap>

<select id="getTeacher" resultType="com.qcby.entity.Teacher">
    SELECT * FROM teacher WHERE id = #{t_id};
</select>

三、一对多 关系映射

1. 直接查询

实体类
public class Teacher {
    private Integer id;
    private String Tname;
    private List<Student> students; // 一个老师有多个学生
}
查询语句
<select id="getTeacher" resultMap="TeacherStudent">
    SELECT teacher.id, teacher.Tname, student.Sname
    FROM teacher
    LEFT JOIN student ON student.t_id = teacher.id;
</select>

<resultMap id="TeacherStudent" type="com.qcby.entity.Teacher">
    <collection property="students" ofType="com.qcby.entity.Student">
        <result property="Sname" column="Sname"/>
    </collection>
</resultMap>

2. 分步查询

<select id="getTeacher" resultMap="TeacherStudent2">
    SELECT * FROM teacher;
</select>

<resultMap id="TeacherStudent2" type="com.qcby.entity.Teacher">
    <collection property="students" column="id" ofType="com.qcby.entity.Student" select="getStudentByTeacherId" />
</resultMap>

<select id="getStudentByTeacherId" resultType="com.qcby.entity.Student">
    SELECT * FROM student WHERE t_id = #{t_id};
</select>

四、MyBatis 延迟加载(懒加载)

1. 配置全局懒加载

<settings>
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

2. 配置分步查询的懒加载

<association property="teacher" column="t_id" javaType="com.qcby.entity.Teacher"
    select="com.qcby.dao.TeacherDao.getTeacher" fetchType="lazy"/>

3. 测试代码

@Test
public void getStudent() {
    List<Student> studentList = mapper.getStudent();
    for (Student student : studentList) {
        System.out.println(student.getSex());
    }
}

@Test
public void getStudentWithTeacher() {
    List<Student> studentList = mapper.getStudent();
    for (Student student : studentList) {
        System.out.println(student.getTeacher().getTname());
    }
}

4. 强制立即加载(eager)

<association property="teacher" column="t_id" javaType="com.qcby.entity.Teacher"
    select="com.qcby.dao.TeacherDao.getTeacher" fetchType="eager"/>

五、总结

  • 一对一 & 多对一 可以使用 连表查询分步查询(懒加载)
  • 一对多 关系可以使用 结果嵌套查询嵌套
  • 懒加载 需要在 MyBatis 配置文件映射 XML 里配置。
  • 某些查询可以强制使用立即加载(eager),避免不必要的多次查询。


http://www.kler.cn/a/524301.html

相关文章:

  • Python GUI 开发 | Qt Designer — 工具介绍
  • pytorch逻辑回归实现垃圾邮件检测
  • 十年筑梦,再创鲸彩!庆祝和鲸科技十周年
  • Nginx 开发总结
  • 工业级 RAG 实现 - QAnything
  • 记录 | 基于Docker Desktop的MaxKB安装
  • OpenEuler学习笔记(十五):在OpenEuler上搭建Java运行环境
  • 【实践】基于SakuraLLM的离线日文漫画及视频汉化
  • HarmonyOS:状态管理最佳实践
  • 联想Y7000+RTX4060+i7+Ubuntu22.04运行DeepSeek开源多模态大模型Janus-Pro-1B+本地部署
  • 中国股市“慢牛”行情的实现路径与展望
  • 如何将 Windows 上的文件传递到 Mac 上
  • Android-音频采集
  • Python 合并 Excel 单元格
  • 望获实时Linux系统:2024回顾与2025展望
  • 代码随想录算法训练营第三十九天-动态规划-198. 打家劫舍
  • 使用kitty terminal遇到的‘xterm-kitty‘: unknown terminal type.
  • 【Convex Optimization Stanford】Lec3 Function
  • 【C++题解】1056. 所有不超过1000的数中含有数字3的自然数
  • 2025年大年初一篇,C#调用GPU并行计算推荐
  • leetcode——二叉树的中序遍历(java)
  • 机器人基础深度学习基础
  • 记忆力训练day08
  • doris:HLL
  • 网络安全攻防实战:从基础防护到高级对抗
  • 园区管理系统如何赋能企业高效运营与资产全生命周期管理