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…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

Canal环境搭建并实现和ES数据同步
作者:田超凡 日期:2025年6月7日 Canal安装,启动端口11111、8082: 安装canal-deployer服务端: https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...