Mybatis:关联映射

一、创建表结构

1.学生表

SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for student -- ---------------------------- 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; -- ---------------------------- -- Records of student -- ---------------------------- INSERT INTO `student` VALUES (1, '张三', '男', 18, 1); INSERT INTO `student` VALUES (2, '李四', '女', 18, 1); INSERT INTO `student` VALUES (3, '王五', '男', 18, 1); INSERT INTO `student` VALUES (4, '小白', '女', 18, 1); INSERT INTO `student` VALUES (5, '小黑', '男', 18, 1); INSERT INTO `student` VALUES (6, '小红', '女', 20, 2); INSERT INTO `student` VALUES (7, '小李', '男', 20, 2); INSERT INTO `student` VALUES (8, '小张', '女', 20, 2); INSERT INTO `student` VALUES (9, '小赵', '男', 20, 2); INSERT INTO `student` VALUES (10, '小王', '女', 20, 2); SET FOREIGN_KEY_CHECKS = 1;

2.老师表

SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for teacher -- ---------------------------- 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; -- ---------------------------- -- Records of teacher -- ---------------------------- INSERT INTO `teacher` VALUES (1, '张老师'); INSERT INTO `teacher` VALUES (2, '李老师'); SET FOREIGN_KEY_CHECKS = 1;

二、一对一、多对一

1.第一种形式 连表查询

SELECT student.id,student.name,teacher.name FROM student LEFT JOIN teacher on student.t_id = teacher.id

①:设置实体类

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"/> <result property="sex" column="sex"/> <result property="age" column="age"/> <result property="t_id" column="t_id"/> <!-- 复杂的属性我们需要单独去处理 对象:association 集合:collection --> <!-- property="teacher" student类当中的关联字段 --> <!-- javaType="com.javen.model.Teacher" 为复杂属性设置类类型--> <association property="teacher" javaType="com.qcby.entity.Teacher"> <result property="id" column="id"/> <result property="Tname" column="Tname"/> </association> </resultMap>

查询每个学生的对应的老师

2.第二种形式 分步查询

SELECT s.id,s.Sname,t.Tname FROM student s,teacher t where s.t_id = t.id

①:设置实体类

这里的实体类不需要变动

②:查询语句

<select id = "getStudent" resultMap="StudentTeacher"> select * from student; </select> <!--结果映射集--> <resultMap id="StudentTeacher" type="com.qcby.entity.Student"> <result property="id" column="id"/> <result property="Sname" column="Sname"/> <result property="sex" column="sex"/> <result property="age" column="age"/> <result property="t_id" column="t_id"/> <!-- select="getTeacher" :调用下一个查询语句 --> <!-- column="t_id" 两个表的关联字段--> <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}; <!-- #{id}; 可以写任何东西,因为会自动匹配 t_id --> </select>

三、一对多

查询每个老师有多少学生

1.第一种形式:按照结果嵌套处理

SELECT teacher.id,teacher.name,student.name FROM teacher LEFT JOIN student on student.t_id = teacher.id

①.设置实体类

public class Student { private Integer id; private String Sname; private String sex; private Integer age; private Integer t_id; }

这里需要将student类当中关于teacher的字段删除

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"> <result property="id" column="id"/> <result property="Tname" column="Tname"/> <!-- 复杂的属性我么需要单独去处理 对象:association 集合:collection 在集合中的泛型信息,我们使用ofType获取 --> <collection property="students" ofType="com.qcby.entity.Student"> <result property="Sname" column="Sname"/> </collection> </resultMap>

2.第二种形式:按照查询嵌套处理

SELECT s.id,s.Sname,t.Tname FROM student s,teacher t where s.t_id = t.id

①.设置实体类

这里的实体类不需要变动

②.查询语句

<!--按照查询嵌套处理--> <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延迟加载策略

以上有两种写法来表示查询信息,分别是链表查询和分步查询的方法。那么既然我么能用一个SQL语句能够执行完,那为什么还要分开来写呢?

原因很简单:同学们可以发现如果我们把他们连在一起那么他们就是一个多表查询语句,如果不放在一起执行,那那就是单独一个表的查询语句。但是这需要我们设置mybatis的延迟加载(懒加载)

分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息

lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载

aggressiveLazyLoding:当开启时,任何方式的调用都会加载该对象的所有属性。否则,该属性会按需加载

此时就可以实现按需加载,需要获取的数据是什么,就只会执行相应的sql.此时会通过association和collection中的fetchType属性设置当前的分步查询是否使用懒加载

fetchType=“lazy(延迟加载) | eager(立即加载)”

1.在主配置文件当中设置延迟加载

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

2.在studentDao.xml当中设置分步查询

<select id = "getStudent" resultMap="StudentTeacher"> select * from student; </select> <!--结果映射集--> <resultMap id="StudentTeacher" type="com.qcby.entity.Student"> <result property="id" column="id"/> <result property="Sname" column="Sname"/> <result property="sex" column="sex"/> <result property="age" column="age"/> <result property="t_id" column="t_id"/> <!-- select="getTeacher" :调用下一个查询语句 --> <!-- select="com.qcby.dao.TeacherDao.getTeacher" :调用下一个查询语句 --> <association property="teacher" column="t_id" javaType="com.qcby.entity.Teacher" select="com.qcby.dao.TeacherDao.getTeacher" fetchType="lazy"/> </resultMap>

3.在TeacherDao.xml当中设置关于教师的查询

<select id="getTeacher" resultType="com.qcby.entity.Teacher" parameterType="java.lang.Integer"> select * from teacher where id = #{t_id}; <!-- #{id}; 可以写任何东西,因为会自动匹配 t_id --> </select>

4.配置TeacherDao

Teacher getTeacher(Integer id);

5.访问设置

①:只访问student当中的内容

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

②:访问全部的内容和有关Teacher表当中的内容时

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

6.一些特殊情况下的查询

我们在主配置文件当中设置的懒加载,对于任何一个分步查询都是有效的,但是在一些特殊的情况下,我们希望有些语句不分开查询,这个时候我们就需要设置该语句只能立即加载

<select id = "getStudent" resultMap="StudentTeacher"> select * from student; </select> <!--结果映射集--> <resultMap id="StudentTeacher" type="com.qcby.entity.Student"> <result property="id" column="id"/> <result property="Sname" column="Sname"/> <result property="sex" column="sex"/> <result property="age" column="age"/> <result property="t_id" column="t_id"/> <!-- select="com.qcby.dao.TeacherDao.getTeacher" :调用下一个查询语句 --> <!-- column="t_id" 两个表的关联字段--> <!--fetchType="eager" 立即加载--> <association property="teacher" column="t_id" javaType="com.qcby.entity.Teacher" select="com.qcby.dao.TeacherDao.getTeacher" fetchType="eager"/> </resultMap>

测试语句

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

五、核心总结

1. 多表关联映射

多对一 / 一对一:使用association标签映射单个关联对象,指定javaType

一对多:使用collection标签映射关联集合,指定ofType(集合元素类型)。

2.查询方式对比

连表查询:SQL 一次联表,性能取决于联表复杂度,适合需要一次性获取所有数据的场景;

分步查询:SQL 拆分,支持延迟加载,按需查询,适合大表 / 多表关联的性能优化。

3.延迟加载关键配置

全局开关:lazyLoadingEnabled=true+aggressiveLazyLoading=false

局部覆盖:fetchType="lazy/eager"可单独控制某一分步查询的加载策略。

通过以上方式,MyBatis 可以灵活处理多表关联场景,同时结合延迟加载有效优化查询性能,适配不同的业务需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1141566.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嘉立创EDA画PCB教程:STM32最小系统设计完整指南

从零开始打造STM32最小系统&#xff1a;嘉立创EDA实战全记录你是不是也曾在搜索“嘉立创eda画pcb教程”时&#xff0c;翻遍资料却仍被一堆术语绕晕&#xff1f;电源不稳、晶振不起、程序下不进去……明明照着电路连的&#xff0c;为什么就是跑不起来&#xff1f;别急。今天我们…

Keil与Proteus联调方法:零基础小白指南

Keil 与 Proteus 联调实战&#xff1a;从零开始搭建虚拟单片机实验室你是否曾因为没有开发板而无法完成单片机作业&#xff1f;是否在调试代码时&#xff0c;对着不亮的 LED 束手无策&#xff0c;却不知是程序写错了还是电路接反了&#xff1f;别担心——Keil 与 Proteus 联调&…

操作指南:利用波特图优化频率响应性能

用波特图“把脉”电路&#xff1a;手把手教你优化频率响应&#xff0c;让系统稳如泰山你有没有遇到过这样的情况&#xff1f;一个电源样机焊好了&#xff0c;输入输出电压都没问题&#xff0c;可一加负载&#xff0c;输出就开始“抽搐”——电压不停振荡&#xff0c;示波器上波…

嵌入式环境下堆溢出导致crash的系统学习

堆溢出为何让嵌入式系统“猝死”&#xff1f;一次 HardFault 背后的真相你有没有遇到过这样的场景&#xff1a;设备在实验室跑得好好的&#xff0c;一到现场却隔三差五重启&#xff1b;调试器抓到的调用栈停在free()里&#xff0c;但代码里明明没写错&#xff1b;翻遍逻辑也找不…

STM32CubeMX教程中SDIO接口初始化项目应用

用STM32CubeMX搞定SDIO&#xff1a;从配置到文件系统的实战全解析在嵌入式开发中&#xff0c;存储大容量数据早已不是“加分项”&#xff0c;而是许多项目的硬性需求。无论是工业设备的日志记录、医疗仪器的采样存储&#xff0c;还是音视频终端的缓存处理&#xff0c;都需要稳定…

⚡_实时系统性能优化:从毫秒到微秒的突破[20260110173735]

作为一名专注于实时系统性能优化的工程师&#xff0c;我在过去的项目中积累了丰富的低延迟优化经验。实时系统对性能的要求极其严格&#xff0c;任何微小的延迟都可能影响系统的正确性和用户体验。今天我要分享的是在实时系统中实现从毫秒到微秒级性能突破的实战经验。 &#…

ModbusTCP协议详解实时性优化在STM32上的实践

ModbusTCP协议详解&#xff1a;在STM32上实现高实时性通信的工程实践工业现场&#xff0c;时间就是控制命脉。一个典型的场景是&#xff1a;主控PLC通过以太网向远程I/O模块读取传感器状态&#xff0c;若响应延迟超过5ms&#xff0c;整个运动控制环路就可能失稳。而当你打开Wir…

REINFORCE 算法

摘要&#xff1a;REINFORCE算法是一种基于蒙特卡洛的策略梯度强化学习方法&#xff0c;由Williams于1992年提出。该算法通过采样完整情节轨迹&#xff0c;计算回报梯度并更新策略参数来优化智能体决策。其优势在于无需环境模型、实现简单且能处理高维动作空间&#xff0c;但存在…

Linux 运维:删除大日志文件时避免磁盘 IO 飙升,echo 空文件 vs truncate 命令对比实操

作为一名摸爬滚打11年的老运维&#xff0c;我踩过无数次“删大日志搞崩服务器”的坑。凌晨4点&#xff0c;监控告警疯狂刷屏&#xff1a;磁盘 IO 使用率 100%&#xff01;业务响应超时&#xff01;排查后发现&#xff0c;是同事直接 rm -rf 了一个 80G 的 Nginx 访问日志——瞬…

ARM Cortex-M开发前必做:Keil5MDK安装与初步设置全面讲解

从零开始搭建ARM开发环境&#xff1a;Keil5MDK安装与配置实战指南 你是不是刚接触嵌入式开发&#xff0c;面对琳琅满目的工具链无从下手&#xff1f; 或者已经下载了Keil但点击“Download”时弹出一堆错误提示&#xff0c;心里直犯嘀咕&#xff1a;“我到底漏了哪一步&#x…

SARSA 强化学习

摘要&#xff1a;SARSA是一种基于在线策略的强化学习算法&#xff0c;其名称来源于"状态-动作-奖励-状态-动作"的学习序列。该算法通过Q值迭代更新&#xff0c;使智能体在环境中通过试错法学习最优策略。核心流程包括Q表初始化、ε-贪婪策略选择动作、执行动作获取奖…

10 分钟搞定 RabbitMQ 高可用:HAProxy 负载均衡实战指南

在分布式系统中&#xff0c;RabbitMQ作为常用消息中间件&#xff0c;集群部署是保障高可用的关键。但很多开发者会遇到一个棘手问题&#xff1a;Java程序直接绑定RabbitMQ节点的IP和端口后&#xff0c;一旦该节点宕机&#xff0c;程序就会连接失败&#xff0c;只能手动修改配置…

告别“算完就忘”:3行代码为Windows打造可审计计算器

面对复杂的四则运算&#xff0c;你是否也经历过对计算结果的自我怀疑&#xff1f;那个藏在电脑角落的批处理文件&#xff0c;每次运行时都在默默为你的每一步计算留下无法抵赖的铁证。 痛点&#xff1a;我们为什么需要“计算留痕”&#xff1f; 在日常工作、财务对账或工程计算…

MDK编译优化选项对C代码的影响:一文说清原理

MDK编译优化选项对C代码的影响&#xff1a;从原理到实战的深度剖析一个困扰无数嵌入式工程师的问题你有没有遇到过这样的场景&#xff1f;调试一段ADC采样代码时&#xff0c;明明在主循环里读取了一个由中断更新的标志变量&#xff0c;但程序就是“卡住”不动——断点停在那里&…

超详细版:CubeMX搭建FreeRTOS与CAN通信驱动流程

从零搭建STM32实时通信系统&#xff1a;CubeMX FreeRTOS CAN 驱动实战指南你有没有遇到过这样的场景&#xff1f;主循环里塞满了ADC采样、LED闪烁、串口打印&#xff0c;突然来了个CAN报文要发&#xff0c;结果因为某个任务卡了几十毫秒&#xff0c;通信直接超时。更糟的是&a…

智慧物流如何重塑云南高原农产品供应链?

&#x1f4cc; 目录&#x1f69b; 松茸24小时直达东京&#xff01;华为智慧冷链改写云南山货命运&#xff1a;从烂半路到全球鲜&#xff0c;数字高铁如何逆袭&#xff1f;一、传统物流的“生死劫”&#xff1a;山货出山&#xff0c;一半耗在半路&#xff08;一&#xff09;核心…

Multisim参数扫描分析:深度剖析其配置技巧

Multisim参数扫描分析实战&#xff1a;从入门到精通的深度指南你有没有过这样的经历&#xff1f;为了调出一个理想的滤波器响应&#xff0c;手动改了十几遍电容值&#xff0c;每次都要重新运行仿真、切换窗口对比曲线&#xff0c;最后不仅眼睛累&#xff0c;还漏掉了关键的转折…

计算机毕设 java 基于 Java 的武夷智能公交系统的设计与实现 智能公交信息管理平台 城市公交路线查询系统

计算机毕设 java 基于 Java 的武夷智能公交系统的设计与实现 d60429&#xff08;配套有源码 程序 mysql 数据库 论文&#xff09;本套源码可以先看具体功能演示视频领取&#xff0c;文末有联 xi 可分享随着城市交通的快速发展和居民出行需求的提升&#xff0c;传统公交管理存在…

HardFault_Handler异常响应流程:图解说明与调试

深入HardFault&#xff1a;从崩溃现场还原真相的实战指南在嵌入式开发的世界里&#xff0c;最让人又爱又恨的一幕莫过于程序突然“挂掉”&#xff0c;调试器一连串断点失效&#xff0c;最终停在一个名为HardFault_Handler的函数入口。它像一道无声的警报——系统出了大问题。但…

计算机毕设 java 基于 Java 的物业管理系统 智能小区物业管控平台 业主服务管理系统

计算机毕设 java 基于 Java 的物业管理系统 97wd59&#xff08;配套有源码 程序 mysql 数据库 论文&#xff09;本套源码可以先看具体功能演示视频领取&#xff0c;文末有联 xi 可分享随着城市化进程的加快和小区管理需求的提升&#xff0c;传统物业管理存在流程繁琐、信息传递…