Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
MyBatis 是一个用于简化数据库操作的框架,它可以帮助开发人员通过映射语句轻松执行 SQL 查询,并且能够方便地实现对象与数据库表之间的映射。MyBatis 支持一对一、一对多和多对多等关联查询。下面我们来探讨一下 MyBatis 如何实现一对一、一对多的关联查询,并了解它们的实现方式及区别。
一、MyBatis中的关联查询
在 MyBatis 中,关联查询通常是通过 映射嵌套结果(Nested Result Mapping)和 嵌套选择(Nested Select)来实现的。你可以在 MyBatis 的映射文件中配置 <resultMap>
和 <association>
、<collection>
等标签来处理这些关联。
二、实现一对一和一对多关联查询的方式
1. 一对一关联查询
一对一关联查询的场景是一个表的记录与另一个表的记录一一对应,通常通过外键关系来实现。
1.1 使用 <association>
标签
在 MyBatis 中,你可以使用 <association>
标签来进行一对一关联查询。它用于将查询结果中的一个字段映射到另一个对象的属性上。
示例:
假设我们有两个表 user
和 address
,其中 user
表包含一个外键 address_id
,指向 address
表。
<!-- UserMapper.xml --> <resultMap id="userResultMap" type="User"> <id property="id" column="user_id"/> <result property="name" column="user_name"/> <association property="address" javaType="Address"> <id property="id" column="address_id"/> <result property="street" column="address_street"/> <result property="city" column="address_city"/> </association> </resultMap> <select id="findUserById" resultMap="userResultMap"> SELECT u.user_id, u.user_name, a.address_id, a.address_street, a.address_city FROM user u LEFT JOIN address a ON u.address_id = a.address_id WHERE u.user_id = #{userId} </select>
在上述示例中,<association>
标签用于将 user
和 address
之间的关联关系映射到 User
类中的 address
属性上。当查询用户时,user
和 address
数据会被映射到 User
对象及其嵌套的 Address
对象中。
2. 一对多关联查询
一对多关联查询的场景是一个表的记录与另一个表的多条记录相关联。通常可以通过子查询或者联合查询来实现。
2.1 使用 <collection>
标签
在 MyBatis 中,<collection>
标签用于表示一对多关系。它可以将查询结果中的多条记录映射到一个集合(如 List
或 Set
)中。
示例:
假设我们有两个表 author
和 book
,其中 author
表和 book
表存在一对多关系,即一个作者可能写多本书。
<!-- AuthorMapper.xml --> <resultMap id="authorResultMap" type="Author"> <id property="id" column="author_id"/> <result property="name" column="author_name"/> <collection property="books" ofType="Book"> <id property="id" column="book_id"/> <result property="title" column="book_title"/> </collection> </resultMap> <select id="findAuthorWithBooks" resultMap="authorResultMap"> SELECT a.author_id, a.author_name, b.book_id, b.book_title FROM author a LEFT JOIN book b ON a.author_id = b.author_id WHERE a.author_id = #{authorId} </select>
在上述示例中,<collection>
标签用于将查询结果中的 book
数据映射到 Author
类的 books
属性中。<collection>
会将多条记录映射成一个集合,通常是 List
类型。
2.2 使用嵌套查询(<select>
标签)
另一种实现一对多关联查询的方式是使用嵌套查询,即在父查询的结果映射中使用 <select>
标签来查询子表的记录。
示例:
<!-- AuthorMapper.xml --> <resultMap id="authorResultMap" type="Author"> <id property="id" column="author_id"/> <result property="name" column="author_name"/> <select property="books" resultType="Book"> SELECT b.book_id, b.book_title FROM book b WHERE b.author_id = #{id} </select> </resultMap> <select id="findAuthorWithBooks" resultMap="authorResultMap"> SELECT a.author_id, a.author_name FROM author a WHERE a.author_id = #{authorId} </select>
在这个例子中,<select>
标签嵌套在 <resultMap>
中,用于查询与父对象 author
关联的 book
数据。这种方式通过执行两次 SQL 查询来获取一对多的关系。
三、关联查询的实现方式对比
1. 使用 <association>
vs <collection>
<association>
标签用于一对一关系,表示一个父对象包含一个子对象,适用于数据库中一对一的场景。<collection>
标签用于一对多关系,表示一个父对象包含多个子对象,适用于数据库中的一对多场景。
2. 联合查询 vs 嵌套查询
- 联合查询(JOIN)通常是将两个表的数据合并成一行来查询。这种方式通常效率较高,但需要注意关联表的数据重复问题(比如一对多关系会导致数据重复)。
- 嵌套查询(
<select>
)是通过额外的查询来获取关联数据,通常适用于复杂的查询场景,特别是当需要处理一对多或多对多关系时。这种方式可能会导致较高的查询开销,但可以提供更灵活的查询结构。
四、总结
- 一对一查询:可以通过
<association>
标签来实现,它适用于一个表的记录与另一个表的记录一一对应的情况。 - 一对多查询:可以通过
<collection>
标签来实现,或者使用嵌套查询(<select>
标签)来执行一对多的查询。 - 区别:
<association>
用于映射一对一的关系,而<collection>
用于映射一对多的关系。- 联合查询一般适用于一对多的一次性查询,但在复杂查询中可能会出现数据重复或性能问题;嵌套查询则可以将父子表分开处理,但可能会导致多个查询的执行,影响性能。
选择合适的实现方式,主要根据查询的复杂度、性能要求和实际业务需求来决定
相关文章:
Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
MyBatis 是一个用于简化数据库操作的框架,它可以帮助开发人员通过映射语句轻松执行 SQL 查询,并且能够方便地实现对象与数据库表之间的映射。MyBatis 支持一对一、一对多和多对多等关联查询。下面我们来探讨一下 MyBatis 如何实现一对一、一对多的关联查…...

ABAP SQL 取日期+时间最新的一条数据
我们在系统对接的时候,外部系统可能会推送多个数据给到我们。 我们 SAP 系统的表数据中日期和时间是作为主键的,那么如果通过 ABAP SQL 取到最新日期的最新时间呢。 解决方案: 方式 1:SELECT MAX 可以通过两个 SELECT MAX 来取…...
【Rust自学】4.3. 所有权与函数
4.3.0 写在正文之前 在学习了Rust的通用编程概念后,就来到了整个Rust的重中之重——所有权,它跟其他语言都不太一样,很多初学者觉得学起来很难。这个章节就旨在让初学者能够完全掌握这个特性。 本章有三小节: 所有权࿱…...

【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
一、什么是分布式锁 我们在上篇文章中实现了单机模式下的秒杀业务。其中采用了synchronized加锁来解决各种线程安全问题。而synchronized关键字是依赖于单机的JVM,在集群模式下,每个服务器都有独立的JVM,如果此时还采用synchronized关键字加…...

用docker快速安装电子白板Excalidraw绘制流程图
注:本文操作以debian12.8 最小化安装环境为host系统。 一、彻底卸载原有的残留 apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras 二、设置docker的安装源 # Add Dockers official G…...

使用Turtle库实现,鼠标左键绘制路径,用鼠标右键结束绘制,小海龟并沿路径移动
使用Turtle库实现,鼠标左键绘制路径,用鼠标右键结束绘制,小海龟并沿路径移动 Turtle库是Python标准库的一部分,它提供了一种基于命令的图形绘制方式。Turtle模块通过一个“海龟”(Turtle)对象在屏幕上移动…...

人工智能入门是先看西瓜书还是先看花书?
在人工智能入门时,关于先看《机器学习》(西瓜书)还是先看《深度学习》(花书)的问题,实际上取决于个人的学习目标和背景。 《机器学习》(西瓜书)由周志华教授撰写,是一本…...
winform中屏蔽双击最大化或最小化窗体(C#实现),禁用任务管理器结束程序,在需要屏蔽双击窗体最大化、最小化、关闭
winform中屏蔽双击最大化或最小化窗体(C#实现),禁用任务管理器结束程序,在需要屏蔽双击窗体最大化、最小化、关闭 protected override void WndProc(ref Message m){#region 处理点击窗体标题栏放大缩小问题,禁用点击窗体标题栏放大缩小//logger.Info($&…...

进程内存转储工具|内存镜像提取-取证工具
1.内存转储,内存转储(Memory Dump)是将计算机的物理内存(RAM)内容复制到一个文件中的过程,这个文件通常被称为“内存转储文件”或“核心转储文件”(Core Dump),内存转储的主要目的是…...

数据结构day5:单向循环链表 代码作业
一、loopLink.h #ifndef __LOOPLINK_H__ #define __LOOPLINK_H__#include <stdio.h> #include <stdlib.h>typedef int DataType;typedef struct node {union{int len;DataType data;};struct node* next; }loopLink, *loopLinkPtr;//创建 loopLinkPtr create();//…...

(OCPP服务器)SteVe编译搭建全过程
注意:建议使用3.6.0,我升级到3.7.1,并没有多什么新功能,反而电表的实时数据只能看到累计电能了,我回退了就正常,数据库是兼容的,java版本换位java11,其他不变就好 背景:…...

Mybatis分页插件的使用问题记录
项目中配置的分页插件依赖为 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.7</version></dependency>之前的项目代码编写分页的方式为,通过传入的条件…...

36. Three.js案例-创建带光照和阴影的球体与平面
36. Three.js案例-创建带光照和阴影的球体与平面 实现效果 知识点 Three.js基础 WebGLRenderer WebGLRenderer 是Three.js中最常用的渲染器,用于将场景渲染到网页上。 构造器 new THREE.WebGLRenderer(parameters)参数类型描述parametersobject可选参数&#…...

CentOS 7 安装、测试和部署FastDFS
目录 FastDFS环境搭建 安装 libfastcommon 库 安装FastDFS 查看编译后的文件 FastDFS配置 FastDFS启动 启动tracker服务 启动storage服务 查看storage是否已经注册到了tracker下 查看存储文件的目录 FastDFS重启 FastDFS关闭 使用fdfs_test进行测试 修改client.co…...

全志H618 Android12修改doucmentsui选中图片资源详情信息
背景: 由于当前的文件管理器在我们的产品定义当中,某些界面有改动的需求,所以需要在Android12 rom中进行定制以符合当前产品定义。 需求: 进入file文件管理器后,点击选中图片资源,选中功能按钮,获取信息,不显示“调试信息(仅开发者)”;现状是,获取信息,显示“调试信…...
【083】基于51单片机智能烘手器【Proteus仿真+Keil程序+报告+原理图】
☆、设计硬件组成:51单片机最小系统LCD1602液晶显示DS18B20温度传感器TCRT5000红外感应传感器AT24C02存储芯片风扇加热片继电器LED灯按键设置。 1、设计采用STC89C51/52、AT89C51/52、AT89S51/52作为主控芯片; 2、系统采用DS18B20温度传感器感应当前环…...

uniApp使用腾讯地图提示未添加maps模块
uniApp使用腾讯地图,打包提示未添加maps模块解决方案 这是报错信息,在标准基座运行的时候是没问题的,但是打包后会提示未添加,可以通过在mainfest里面把地图插件上腾讯地图的key更换高德地图的key,定位服务可以继续用腾…...
未来趋势系列 篇五:自主可控科技题材解析和股票梳理
文章目录 系列文章自主可控科技题材分析国产算力信创(信息技术应用创新)华为鸿蒙军工信息化半导体芯片卫星互联网工业软件股票梳理系列文章 未来趋势系列 篇一:AI题材解析和股票梳理 未来趋势系列 篇一(加更):AI医疗题材解析和股票梳理 未来趋势系列 篇二:HBM题材解析和…...
Springboot 学习 之 logback-spring.xml 日志压缩 .tmp 临时文件问题
文章目录 前言功能简述1. 自定义日志文件名2. 归档规则 && 压缩2.1. 归档配置2.2. 归档压缩2.3. 日志格式 && 编码 现象原因解决办法 前言 在 Springboot 应用中,默认使用 logback-spring.xml 配置日志相关 功能简述 1. 自定义日志文件名 <fi…...

maven-resources-production:ratel-fast: java.lang.IndexOutOfBoundsException
Maven生产环境中遇到java.lang.IndexOutOfBoundsException的问题,尝试了重启电脑、重启IDEA等常规方法无效,最终通过直接重建工程解决了问题。 Rebuild Project 再启动OK...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...