MyBatis中一对多关系的两种处理方法
目录
1.多表联查(通过collection标签的ofType属性)
1)mapper
2)mapper.xml
3)测试代码
4)测试结果
2.分布查询(通过collection标签的select属性)
1)mapper
2)mapper.xml
3)测试代码
4)测试结果
附录
1.Classes实体类
2.student类
3.OneToManyMapper
4.OneToManyMapper.xml
5.OneToManyMapperTest.xml
6.sql
studentSql
classesSql
1.多表联查(通过collection标签的ofType属性)
1)mapper
/*** collectionBy ofType*/ Classes queryClassesAndStudentBycollection(@Param("id") int id);
2)mapper.xml
<!--collection--> <resultMap id="collectionResultMap" type="org.xiji.enty.Classes"><id property="cid" column="cid"/><result property="className" column="className"/><!--collection--><collection property="students" ofType="org.xiji.enty.Student"><id property="sid" column="sid"/><result property="studentName" column="studentName"/><result property="studentAge" column="studentAge"/><result property="classId" column="cid"/></collection></resultMap> <select id="queryClassesAndStudentBycollection" resultMap="collectionResultMap" >select * from classes c right join student s on c.cid = s.classId where c.cid=#{id} </select>
解释:
- 主对象映射
- MyBatis 使用 resultMap 将查询结果映射到 Classes 对象上。
- 主键 cid 和属性 className 直接映射到对应的数据库列。
- 集合映射
- collection 标签用于映射 Classes 对象中的 students 集合。
- 每个 Student 对象的属性 sid, studentName, studentAge, classId 分别映射到对应的数据库列。
3)测试代码
/*** 通过collection关联查询*/ @Test public void queryClassesAndStudentByAssociation() {Classes classes = oneToManyMapper.queryClassesAndStudentBycollection(1);System.out.println(classes);List<Student> students = classes.getStudents();for (Student student : students) {System.out.println(student.toString());} }
4)测试结果

2.分布查询(通过collection标签的select属性)
1)mapper
/*** 分布查询*/ Classes queryClassesAndStudentByStep(@Param("id") int id);/*** 查询id*/ List<Student> queryClassesAndStudentByStepTwo(int id);
2)mapper.xml
<!--通过分布查询--> <resultMap id="stepResultMap" type="org.xiji.enty.Classes"><id property="cid" column="cid"/><result property="className" column="className"/><collection property="students"select="queryClassesAndStudentByStepTwo"column="cid"ofType="org.xiji.enty.Student"><id property="sid" column="sid"></id><result property="classId" column="classId"></result><result property="studentName" column="studentName"></result><result property="studentAge" column="studentAge"></result></collection></resultMap><select id="queryClassesAndStudentByStep" resultMap="stepResultMap" >select *from classes where cid=#{id}; </select><select id="queryClassesAndStudentByStepTwo" resultType="org.xiji.enty.Student">select * from student where classId=#{id} </select>j
解释:
- 主对象映射
- MyBatis 使用 resultMap 将查询结果映射到 Classes 对象上。
- 主键 cid 和属性 className 直接映射到对应的数据库列。
- 分布查询
- collection 标签用于映射 Classes 对象中的 students 集合。
- 通过 select 属性指定另一个映射语句的 ID,用于执行分布查询。
- column 属性指定传递给分布查询的参数列名称,这里是 cid 列。
- 子对象映射
- 每个 Student 对象的属性 sid, classId, studentName, studentAge 分别映射到对应的数据库列。
3)测试代码
/*** 通过collection分布查询*/ @Test public void queryClassesAndStudentByStep() {Classes classes = oneToManyMapper.queryClassesAndStudentByStep(1);System.out.println(classes);List<Student> students = classes.getStudents();for (Student student : students) {System.out.println(student);} }
4)测试结果

附录
1.Classes实体类
package org.xiji.enty;import java.util.ArrayList;
import java.util.List;
import org.xiji. enty.Student;/*** 班级表*/
public class Classes {private int cid;private String className;List<Student> students;public List<Student> getStudents() {return students;}public Classes(int id, String className, List<Student> students) {this.cid = id;this.className = className;this.students = students;}public Classes() {students = new ArrayList<>();}public Classes(int id, String className) {this.cid = id;this.className = className;}public int getId() {return cid;}public void setId(int id) {this.cid = id;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}public void setStudents(List<Student> students) {this.students = students;}@Overridepublic String toString() {return "Classes{" +"id=" + cid +", className='" + className + '\'' +", students=" + students +'}';}
}
2.student类
package org.xiji.enty;
import org.xiji.enty.Classes;/*** 学生表*/
public class Student {private int sid;private String studentName;private int studentAge;private int classId;private Classes classes;public Student(int id, String studentName, int studentAge, int classId, Classes classes) {this.sid = id;this.studentName = studentName;this.studentAge = studentAge;this.classId = classId;this.classes = classes;}public Student(int id, String studentName, int studentAge, int classId) {this.sid = id;this.studentName = studentName;this.studentAge = studentAge;this.classId = classId;}public Student() {}public int getId() {return sid;}public void setId(int id) {this.sid = id;}public String getStudentName() {return studentName;}public void setStudentName(String studentName) {this.studentName = studentName;}public int getStudentAge() {return studentAge;}public void setStudentAge(int studentAge) {this.studentAge = studentAge;}public int getClassId() {return classId;}public void setClassId(int classId) {this.classId = classId;}public Classes getClasses() {return classes;}public void setClasses(Classes classes) {this.classes = classes;}public void setClasses(int id,String className){this.classes = new Classes(id,className);}@Overridepublic String toString() {return "Student{" +"id=" + sid +", studentName='" + studentName + '\'' +", studentAge=" + studentAge +", classId=" + classId +", classes=" + classes +'}';}
}
3.OneToManyMapper
package org.xiji.mapper;import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.xiji.enty.Classes; import org.xiji.enty.Student;import java.util.List;@Mapper public interface OneToManyMapper {/*** association*/Classes queryClassesAndStudentByAssociation(@Param("id") int id);/*** 分布查询*/Classes queryClassesAndStudentByStep(@Param("id") int id);/*** 查询id*/List<Student> queryClassesAndStudentByStepTwo(int id);}
4.OneToManyMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="org.xiji.mapper.OneToManyMapper"><!--collection--><resultMap id="collectionResultMap" type="org.xiji.enty.Classes"><id property="cid" column="cid"/><result property="className" column="className"/><!--collection--><collection property="students" ofType="org.xiji.enty.Student"><id property="sid" column="sid"/><result property="studentName" column="studentName"/><result property="studentAge" column="studentAge"/><result property="classId" column="cid"/></collection></resultMap><select id="queryClassesAndStudentByAssociation" resultMap="collectionResultMap" >select * from classes c right join student s on c.cid = s.classId where c.cid=#{id}</select><!--通过分布查询--><resultMap id="stepResultMap" type="org.xiji.enty.Classes"><id property="cid" column="cid"/><result property="className" column="className"/><collection property="students"select="queryClassesAndStudentByStepTwo"column="cid"ofType="org.xiji.enty.Student"><id property="sid" column="sid"></id><result property="classId" column="classId"></result><result property="studentName" column="studentName"></result><result property="studentAge" column="studentAge"></result></collection></resultMap><select id="queryClassesAndStudentByStep" resultMap="stepResultMap" >select *from classes where cid=#{id};</select><select id="queryClassesAndStudentByStepTwo" resultType="org.xiji.enty.Student">select * from student where classId=#{id}</select></mapper>
5.OneToManyMapperTest.xml
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.xiji.enty.Classes; import org.xiji.enty.Student; import org.xiji.mapper.ManyToOneMapper; import org.xiji.mapper.OneToManyMapper;import java.util.List;@SpringJUnitConfig(locations = {"classpath:springConfig.xml"}) public class OneTwoManyMapperTest {@Autowiredprivate OneToManyMapper oneToManyMapper;/*** 通过collection关联查询*/@Testpublic void queryClassesAndStudentByAssociation(){Classes classes = oneToManyMapper.queryClassesAndStudentByAssociation(1);System.out.println(classes);List<Student> students = classes.getStudents();for (Student student : students) {System.out.println(student.toString());}}/*** 通过collection分布查询*/@Testpublic void queryClassesAndStudentByStep(){Classes classes = oneToManyMapper.queryClassesAndStudentByStep(1);System.out.println(classes);List<Student> students = classes.getStudents();for (Student student : students) {System.out.println(student);}} }
6.sql
studentSql
/*Navicat Premium Data TransferSource Server : mybatisSource Server Type : MySQLSource Server Version : 80025Source Host : localhost:3306Source Schema : mybatisTarget Server Type : MySQLTarget Server Version : 80025File Encoding : 65001Date: 15/09/2024 23:50:47 */SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;-- ---------------------------- -- Table structure for student -- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` (`sid` int NOT NULL AUTO_INCREMENT COMMENT '学生id',`studentName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '学生姓名',`studentAge` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '学生年龄',`classId` int NULL DEFAULT NULL COMMENT '班级id',PRIMARY KEY (`sid`) USING BTREE,INDEX `classId`(`classId` ASC) USING BTREE,CONSTRAINT `classId` FOREIGN KEY (`classId`) REFERENCES `classes` (`cid`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;-- ---------------------------- -- Records of student -- ---------------------------- INSERT INTO `student` VALUES (1, '张三', '18', 1); INSERT INTO `student` VALUES (2, '李四', '20', 1); INSERT INTO `student` VALUES (3, '小久', '21', 1); INSERT INTO `student` VALUES (4, 'xiji', '22', 1);SET FOREIGN_KEY_CHECKS = 1;
classesSql
/*Navicat Premium Data TransferSource Server : mybatisSource Server Type : MySQLSource Server Version : 80025Source Host : localhost:3306Source Schema : mybatisTarget Server Type : MySQLTarget Server Version : 80025File Encoding : 65001Date: 15/09/2024 23:51:16 */SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;-- ---------------------------- -- Table structure for classes -- ---------------------------- DROP TABLE IF EXISTS `classes`; CREATE TABLE `classes` (`cid` int NOT NULL AUTO_INCREMENT COMMENT '班级id',`className` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '班级名称',PRIMARY KEY (`cid`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;-- ---------------------------- -- Records of classes -- ---------------------------- INSERT INTO `classes` VALUES (1, '一班'); INSERT INTO `classes` VALUES (2, '二班'); INSERT INTO `classes` VALUES (3, '三班'); INSERT INTO `classes` VALUES (5, '五班');SET FOREIGN_KEY_CHECKS = 1;
相关文章:
MyBatis中一对多关系的两种处理方法
目录 1.多表联查(通过collection标签的ofType属性) 1)mapper 2)mapper.xml 3)测试代码 4)测试结果 2.分布查询(通过collection标签的select属性) 1)mapper 2)mapper.xml 3࿰…...
视频美颜SDK与直播美颜工具的实现原理与优化方案
本篇文章,小编将为大家详细讲解视频美颜SDK的实现原理,并提出优化方案。 一、视频美颜SDK的实现原理 1.图像采集与处理 2.人脸识别与关键点检测 3.美颜滤镜与特效处理 4.实时性与低延迟 二、直播美颜工具的实现原理 直播美颜工具与视频美颜SDK的…...
Linux 安装JDK8和卸载
目录 一、下载JDK8的rpm包 二、安装JDK 三、设置环境变量 Linux环境下安装JDK的方式有多种,可以通过rpm包、yum安装或者tar.gz压缩包。本章节会教大家通过前两者方式来安装JDK,压缩包的形式因为下载压缩包后上传到服务器环境下,将压缩包解…...
javascript 浏览器打印不同页面设置方向,横向纵向打印
// 在JavaScript中添加打印样式 const printStyle document.createElement(style); printStyle.innerHTML media print { page { size: landscape; }body { margin: 10mm; } }; document.head.appendChild(printStyle);// 触发打印 function printPage() {window.print(); }/…...
Maven 的多种打jar包方式详细介绍、区别及使用教程——附使用命令
文章目录 1. **标准 JAR 打包****打包方式****配置示例****使用方式****优点****缺点** 2. **可执行 JAR(Executable JAR)****打包方式****配置示例****使用方式****优点****缺点** 3. **Uber JAR(Fat JAR / Shadow JAR)****打包方…...
计算机毕业设计 基于协同过滤算法的个性化音乐推荐系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试
🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…...
Arthas 全攻略:让调试变得简单
文章目录 一、简介二、命令列表 一、简介 注意 : 我安装的版本是:Arthas V3.7.2 官网:https://arthas.aliyun.com/doc/ 相关错误解决方案请看GitHub:https://github.com/alibaba/arthas/issues Alibaba开源的Java诊断工具。 从…...
icpc江西:L. campus(dij最短路)
题目 在樱花盛开的季节,西湖大学吸引了大量游客,这让胥胥非常烦恼。于是,他发明了一个神奇的按钮,按下按钮后,校园里所有的游客都会以光速从最近的大门离开学校。现在,胥胥非常好奇,游客们以光…...
日志收集工具 Fluentd vs Fluent Bit 的区别
参考链接: FluentdFluentd BitFluentd & Fluent Bit | Fluent Bit: Official Manual Fluentd 与 Fluent Bit 两者都是生产级遥测生态系统! 遥测数据处理可能很复杂,尤其是在大规模处理时。这就是创建 Fluentd 的原因。 Fluentd 不仅仅是…...
PostgreSQL技术内幕11:PostgreSQL事务原理解析-MVCC
文章目录 0.简介1.MVCC介绍2.MVCC常见的实现方式3.PG的MVCC实现3.1 可见性判断3.2 提交/取消 0.简介 本文主要介绍在事务模块中MVCC(多版本并发控制)常见的实现方式,优缺点以及PG事务模块中MVCC(多版本并发控制)的实现。 1.MVCC…...
Java-面向对象编程(基础部分)
类和对象的区别和联系 类:类是封装对象的属性和行为的载体,在Java语言中对象的属性以成员变量的形式存在,而对象的方法以成员方法的形式存在。 对象:Java是面向对象的程序设计语言,对象是由类抽象出来的,…...
SMS over IP原理
目录 1. 短消息业务的实现方式 2. 传统 CS 短消息业务中的发送与送达报告 3. MAP/CAP 信令常见消息 4. SMS over IP 特点概述 5. SMS over IP 中的主要流程 5.1 短消息注册流程(NR 或 LTE 接入) 5.2 短消息发送(MO)流程(NR 或 LTE 接入) 5.3 短消息接收(MT)流程(NR 或…...
Linux中使用Docker容器构建Tomcat容器完整教程
🏡作者主页:点击! 🐧Linux基础知识(初学):点击! 🐧Linux高级管理防护和群集专栏:点击! 🔐Linux中firewalld防火墙:点击! ⏰️创作…...
【机器学习】7 ——k近邻算法
机器学习7——k近邻 输入:实例的特征向量 输出:类别 懒惰学习(lazy learning)的代表算法 文章目录 机器学习7——k近邻1.k近邻2.模型——距离,k,分类规则2.1距离——相似程度的反映2.2 k值分类规则 算法实…...
2024.09.09 校招 实习 内推 面经
🛰️ :neituijunsir 交* 流*裙 ,内推/实习/校招汇总表格 1、校招 | 佑驾创新 MINIEYE 2025校园招聘正式启动(内推) 校招 | 佑驾创新 MINIEYE 2025校园招聘正式启动(内推) 2、校招 | 长安汽…...
浅谈Linux中的环回设备
什么是环回设备 环回设备(loop device) 是 Linux 系统中一种特殊的虚拟设备,它允许你将一个普通的文件当作块设备来操作。这意味着,借助环回设备,文件可以模拟为一个磁盘或分区,供系统读写。这种机制非常有…...
聚焦汽车智能化与电动化,亚洲领先的汽车工业技术博览会 2025年11月与您相约 AUTO TECH 华南展
抢占市场先机︱聚焦汽车智能化与电动化,亚洲领先的汽车工业技术博览会 2025年11月与您相约 AUTO TECH 华南展 随着汽车智能化与电动化的迅猛发展,汽车电子技术、车用功率半导体技术、智能座舱技术、轻量化技术/材料、软件定义汽车、EV/HV技术、测试测量技…...
(史上最全)线程池
线程池 文章目录 线程池一,前言二,线程池三,参数四,线程池的实现原理5.线程池的使用案例(自定义线程池)6.使用Executors 创建常见的功能线程池1.固定大小线程池2.定时线程3.可缓存线程池4.单线程化线程池 一,前言 虽然…...
【ShuQiHere】 支持向量机(SVM)详解:从理论到实践,这一篇就够了
📖 【ShuQiHere】 在现代机器学习课程中,支持向量机(SVM) 是不可或缺的一部分。它不仅在分类任务中有出色表现,还能灵活处理回归问题。尽管看似复杂,SVM 背后的思想却深刻而优雅。今天我们将全面探讨**支持…...
log4j2线程级动态日志级别
详见 参考 着重说明: DynamicThresholdFilter: 配置长这样:配置解释链接 <DynamicThresholdFilter key"logLevel" defaultThreshold"ERROR" onMatch"ACCEPT" onMismatch"DENY"><KeyVa…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
Qt的学习(一)
1.什么是Qt Qt特指用来进行桌面应用开发(电脑上写的程序)涉及到的一套技术Qt无法开发网页前端,也不能开发移动应用。 客户端开发的重要任务:编写和用户交互的界面。一般来说和用户交互的界面,有两种典型风格&…...
可下载旧版app屏蔽更新的app市场
软件介绍 手机用久了,app越来越臃肿,老手机卡顿成常态。这里给大家推荐个改善老手机使用体验的方法,还能帮我们卸载不需要的app。 手机现状 如今的app不断更新,看似在优化,实则内存占用越来越大,对手机性…...
python3GUI--基于PyQt5+DeepSort+YOLOv8智能人员入侵检测系统(详细图文介绍)
文章目录 一.前言二.技术介绍1.PyQt52.DeepSort3.卡尔曼滤波4.YOLOv85.SQLite36.多线程7.入侵人员检测8.ROI区域 三.核心功能1.登录注册1.登录2.注册 2.主界面1.主界面简介2.数据输入3.参数配置4.告警配置5.操作控制台6.核心内容显示区域7.检…...
