mybatis的多对一、一对多的用法
目录
1、使用VO聚合对象(可以解决这两种情况)
多对一:
一对多:
2、非聚合的多对一做法:
3、非聚合的一对多做法:
1、使用VO聚合对象(可以解决这两种情况)
当我需要多对一、一对多时,可以创建VO聚合对象。
例如:学生类和老师类,会出现多对一、一对多的情况。此时创建一个聚合类,里面包含所需要的学生类和老师类的属性。并先查询出前面的内容,再根据前面的内容查询出后面的内容。
多对一:
数据库设计,学生表中有一个tid来匹配老师id:


在学生类和老师类后,再创建出一个聚合类:
@Data
public class Student {private Integer id;private String username;private Integer tid;
}
@Data
public class Teacher {private Integer id;private String username;
}
@Data
public class StudentAndTeacher {private Integer id;private String username;private Teacher teacher;
}
写出查询所有学生和根据学生类里的tid查询老师:
@Mapper
public interface AllMapper {List<Student> AllStudent();Teacher AllTeacherByTid(Integer tid);
}
<select id="AllStudent" resultType="com.example.demo.entity.Student">select * from student;</select><select id="AllTeacherByTid" resultType="com.example.demo.entity.Teacher">select * from teacher where id=#{tid};</select>
通过聚合类,把这两个查询到的内容聚合到一起:
@Testpublic void AllStudent() {List<Student> students = allMapper.AllStudent();for (Student student : students) {StudentAndTeacher studentAndTeacher = new StudentAndTeacher();studentAndTeacher.setId(student.getId());studentAndTeacher.setUsername(student.getUsername());studentAndTeacher.setTeacher(allMapper.AllTeacherByTid(student.getTid()));System.out.println(studentAndTeacher);}}
结果如下:

一对多:
学生类和老师类一样,但是聚合类不一样,因为现在的主体是老师,而不是学生。
@Data
public class Student {private Integer id;private String username;private Integer tid;
}
@Data
public class Teacher {private Integer id;private String username;
}
@Data
public class TeacherAndStudent {private Integer id;private String username;private List<Student> studentList;
}
写出查询所有老师和根据老师的id去学生表里查对应tid的学生:
@Mapper
public interface AllMapper {List<Teacher> AllTeacher();List<Student> AllStudentById(Integer id);
}
<select id="AllTeacher" resultType="com.example.demo.entity.Teacher">select * from teacher;</select><select id="AllStudentById" resultType="com.example.demo.entity.Student">select * from student where tid=#{id};</select>
通过聚合类,把这两个查询到的内容聚合到一起:
@Testpublic void AllTeacher() {List<Teacher> Teachers = allMapper.AllTeacher();for (Teacher teacher : Teachers) {List<Student> students = allMapper.AllStudentById(teacher.getId());TeacherAndStudent studentAndTeacher = new TeacherAndStudent();studentAndTeacher.setId(teacher.getId());studentAndTeacher.setUsername(teacher.getUsername());studentAndTeacher.setStudentList(students);System.out.println(studentAndTeacher);}}
结果如下:

2、非聚合的多对一做法:
知识点:association标签是用在多对一时,当一个类中有其他类作为该类的属性时,要用到这个标签。
此时的Student类中有一个属性是Teacher类:
@Data
public class Student {private Integer id;private String username;private Teacher teacher;
}
@Data
public class Teacher {private Integer id;private String username;
}
@Mapper
public interface AllMapper {List<Student> AllStudent();
}
这里用resultMap来匹配。
要注意两点:
1、result 标签里的property对应的是java类的属性名,column对应的是select 标签里查询出来的字段名。并且要注意,若多个表的字段名相同,必须要用别名区分,并在column中写上别名而非字段名。
2、association 标签中,property对应的是Student类中的teacher属性,类型为Student类,这里的类型用javaType而不是Type。
<select id="AllStudent" resultMap="StudentAndTeacher">select s.id sid, s.username susername, t.id tid, t.username tusernamefrom student s, teacher twhere s.tid = t.id;</select><resultMap id="StudentAndTeacher" type="com.example.demo.entity.Student"><result property="id" column="sid"></result><result property="username" column="susername"></result><association property="teacher" javaType="com.example.demo.entity.Teacher"><result property="id" column="tid"></result><result property="username" column="tusername"></result></association></resultMap>
@Testpublic void StudentAndTeacher() {List<Student> students = allMapper.AllStudent();for (Student student : students) {System.out.println(student);}}
结果如下:

3、非聚合的一对多做法:
知识点:collection标签是用在一对多时,当一个类中有其他类集合作为该类的属性时,要用到这个标签。
此时的Teacher类中有一个属性是List<Student>:
@Data
public class Student {private Integer id;private String username;private Integer tid;
}
@Data
public class Teacher {private Integer id;private String username;private List<Student> students;
}
@Mapper
public interface AllMapper {List<Teacher> AllTeacher();
}
这里用resultMap来匹配。
要注意两点:
1、result 标签里的property对应的是java类的属性名,column对应的是select 标签里查询出来的字段名。并且要注意,若多个表的字段名相同,必须要用别名区分,并在column中写上别名而非字段名。
2、collection标签中,property对应的是Teacher类中的students属性,类型为List,这里的类型用javaType而不是Type,ofType指的是List的泛型。
<select id="AllTeacher" resultMap="TeacherAndStudent">select s.id sid, s.username susername, s.tid stid, t.id tid, t.username tusernamefrom student s, teacher twhere s.tid = t.id;</select><resultMap id="TeacherAndStudent" type="com.example.demo.entity.Teacher"><result property="id" column="tid"></result><result property="username" column="tusername"></result><collection property="students" javaType="List" ofType="com.example.demo.entity.Student"><result property="id" column="sid"></result><result property="username" column="susername"></result><result property="tid" column="stid"></result></collection></resultMap>
@Testpublic void StudentAndTeacher() {List<Teacher> teachers = allMapper.AllTeacher();for (Teacher teacher : teachers) {System.out.println(teacher);}}
此时结果:

相关文章:
mybatis的多对一、一对多的用法
目录 1、使用VO聚合对象(可以解决这两种情况) 多对一: 一对多: 2、非聚合的多对一做法: 3、非聚合的一对多做法: 1、使用VO聚合对象(可以解决这两种情况) 当我需要多对一、一对…...
消息队列实战指南:三大MQ 与 Kafka 适用场景全解析
前言:在当今数字化时代,分布式系统和大数据处理变得愈发普遍,消息队列作为其中的关键组件,承担着系统解耦、异步通信、流量削峰等重要职责。ActiveMQ、RabbitMQ、RocketMQ 和 Kafka 作为市场上极具代表性的消息队列产品࿰…...
前端发送Ajax请求的技术Axios
目录 1.引入Axios文件 2.使用Axios发送请求 2.1请求方法的别名 请求的URL地址怎么来的? 后端实现 前后端交互 1.引入Axios文件 <script src"https://unpkg.com/axios/dist/axios.min.js"></script> 2.使用Axios发送请求 2.1请求方法的…...
第17章:Python TDD回顾与总结货币类开发
写在前面 这本书是我们老板推荐过的,我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后,我突然思考,对于测试开发工程师来说,什么才更有价值呢?如何让 AI 工具更好地辅助自己写代码,或许…...
opencv_KDTree_搜索介绍及示例
cv::flann::KDTreeIndexParams 说明,使用? cv::flann::KDTreeIndexParams 是 OpenCV 中用于配置 KD 树(K-Dimensional Tree)索引参数的类。KD 树是一种用于多维空间中的点搜索的数据结构,常用于最近邻搜索等问题。在…...
Windows 上安装 MongoDB 的 zip 包
博主介绍: 大家好,我是想成为Super的Yuperman,互联网宇宙厂经验,17年医疗健康行业的码拉松奔跑者,曾担任技术专家、架构师、研发总监负责和主导多个应用架构。 近期专注: RPA应用研究,主流厂商产…...
先进制造aps专题二十七 西门子opcenter aps架构分析
欧美的商业aps,主要就是sap apo,西门子opcenter aps,达索quintiq 从技术的层面,西门子aps是不如sap apo的,但是西门子aps是西门子数字化工厂产品的核心,有很多特色,所以分析 西门子aps主要分计划器和排产器两个部分 计…...
【数据分享】1929-2024年全球站点的逐年平均气温数据(Shp\Excel\无需转发)
气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、湿度等指标,其中又以气温指标最为常用!说到气温数据,最详细的气温数据是具体到气象监测站点的气温数据!本次我们为大家带来的就是具体到气象监…...
机器学习——什么是代价函数?
1.代价函数的定义 首先,提到代价函数是估计值和实际值的差,这应该是指预测值和真实值之间的差异,用来衡量模型的好坏。 在一元线性模型中,模型是直线,有两个参数,可能是斜率和截距。 通过调整这两个参数,让代价函数最小,这应该是说我们要找到最佳的斜率和截距,使得预测…...
docker 部署 MantisBT
1. docker 安装MantisBT docker pull vimagick/mantisbt:latest 2.先运行实例,复制配置文件 docker run -p 8084:80 --name mantisbt -d vimagick/mantisbt:latest 3. 复制所需要配置文件到本地路径 docker cp mantisbt:/var/www/html/config/config_inc.php.…...
02内存结构篇(D1_自动内存管理)
目录 一、内存管理 1. C/C程序员 2. Java程序员 二、运行时数据区 1. 程序计数器 2. Java虚拟机栈 3. 本地方法栈 4. Java堆 5. 方法区 运行时常量池 三、Hotspot运行时数据区 四、分配JVM内存空间 分配堆的大小 分配方法区的大小 分配线程空间的大小 一、内存管…...
Centos 8 交换空间管理
新增swap 要增加 Linux 系统的交换空间,可以按照以下步骤操作: 1. 创建一个交换文件 首先,选择文件路径和大小(例如,增加 1 GB 交换空间)。 sudo fallocate -l 1G /swapfile如果 fallocate 不可用&…...
“深入浅出”系列之数通篇:(5)TCP的三次握手和四次挥手
TCP(传输控制协议)的三次握手和四次挥手是TCP连接建立和释放的过程。 一、TCP三次握手 TCP三次握手是为了建立可靠的连接,确保客户端和服务器之间的通信能力。具体过程如下: 第一次握手:客户端向服务器发送一个带有…...
接口测试及接口测试常用的工具
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 首先,什么是接口呢? 接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口。 系统对外的接口ÿ…...
使用rpc绕过咸鱼sign校验
案例网站是咸鱼 找到加密函数i(),发现参数是由token时间戳appkeydata构成的 js客户端服务 考虑到网站可能有判断时间戳长短而让请求包失效的可能,我们请求包就直接用它的方法生成 下面我们先把token和h置为键值对tjh123 再把方法i()设为全局变量my_…...
NPC与AI深度融合结合雷鸟X3Pro AR智能眼镜:引领游戏行业沉浸式与增强现实新纪元的畅想
if… NPC(非玩家角色)与AI(人工智能)的深度融合,正引领游戏行业迈向一个全新的沉浸式与增强现实(AR)相结合的新时代。这一创新不仅预示着游戏体验的质变,更可能全面革新游戏设计与叙…...
【物联网】ARM核介绍
文章目录 一、芯片产业链1. CPU核(1)ARM(2)MIPS(3)PowerPc(4)Intel(5)RISC-V 2. SOC芯片(1)主流厂家(2)产品解决方案 3. 产品 二、ARM核发展1. 不同架构的特点分析(1)VFP(2)Jazelle(3)Thumb(4)TrustZone(5)SIMD(6)NEON 三、ARM核(ARMv7)工作模式1. 权限级别(privilege level)2.…...
Android系统定制APP开发_如何对应用进行系统签名
前言 当项目开发需要使用系统级别权限或frame层某些api时,普通应用是无法使用的,需要在AndroidManifest中配置sharedUserId: AndroidManifest.xml中的android:sharedUserId“android.uid.system”,代表的意思是和系统相同的uid&a…...
Tesla Free-Fall Attack:特斯拉汽车网络安全事件纪要
Tesla Free-Fall Attack:特斯拉汽车网络安全事件纪要 1. 引言 Tesla Free-Fall Attack 是由腾讯科恩实验室(Tencent Keen Security Lab)于2016年9月对特斯拉Model S汽车实施的一次远程攻击事件,揭示了汽车网络安全的严重漏洞&am…...
网络安全工程师学习路线
https://www.processon.com/view/link/6584f06465b7eb6189e99508 1、HTML基本语言 常用标签、表单、上传页面、登录页面、超链接2、javascript基本语法 变量、函数、流程控制语法、post请求、ajax请求、输入数据到页面、文件上传3、mysql基本用法 增删改查 infromation_sch…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
