MyBatis系统学习(四)——MyBatis的关联映射和缓存机制
MyBatis 是一个优秀的持久层框架,它通过 XML 或注解将 Java 对象与 SQL 语句相映射,简化了 JDBC 代码,增强了 SQL 的灵活性。在复杂业务场景中,数据库表之间经常存在一对一、一对多、多对多的关联关系,MyBatis 提供了相应的机制来处理这些映射问题。此外,MyBatis 的缓存机制可以有效提高数据访问效率。
接下来,我将详细介绍 MyBatis 中的关联映射和缓存机制。
一、MyBatis 关联映射概述
在关系型数据库中,表与表之间的关联关系常见的有:
- 一对一(One-to-One):两个表中一条记录对应另一个表中的一条记录。
- 一对多(One-to-Many):一个表中一条记录对应另一个表中的多条记录。
- 多对多(Many-to-Many):两个表中的多条记录彼此关联。
MyBatis 提供了以下两种主要方式来实现关联映射:
- 使用
resultMap标签进行复杂的对象关系映射。 - 通过注解来实现简单的映射。
二、一对一查询
一对一关系通常体现在数据库中表与表之间通过外键关联。MyBatis 支持通过 resultMap 标签来定义一对一的关联关系。
实现步骤:
- 在数据库中,两个表具有外键关联。例如,
User表和Address表,User表有一个address_id外键指向Address表。 - 在 MyBatis 的配置文件中,通过
resultMap定义关联关系。
示例:
假设我们有 User 和 Address 表,User 表中有一个 address_id 作为外键关联 Address 表。
<!-- 一对一映射 resultMap -->
<resultMap id="userResultMap" type="com.example.User"><id property="id" column="id"/><result property="name" column="name"/><association property="address" javaType="com.example.Address"><id property="id" column="address_id"/><result property="city" column="city"/><result property="street" column="street"/></association>
</resultMap><select id="selectUserWithAddress" resultMap="userResultMap">SELECT u.id, u.name, a.id AS address_id, a.city, a.streetFROM User uLEFT JOIN Address a ON u.address_id = a.idWHERE u.id = #{id}
</select>
这里,<association> 用于描述一对一的关系。User 对象的 address 属性将与 Address 对象对应。
三、一对多查询
一对多关系通常表示一个表中的一条记录可以对应另一个表中的多条记录。MyBatis 可以通过 collection 标签来处理一对多的关系。
示例:
假设 User 表和 Order 表存在一对多的关系,一个用户可以有多个订单。
<!-- 一对多映射 resultMap -->
<resultMap id="userWithOrdersResultMap" type="com.example.User"><id property="id" column="id"/><result property="name" column="name"/><collection property="orders" ofType="com.example.Order"><id property="id" column="order_id"/><result property="orderNumber" column="order_number"/><result property="amount" column="amount"/></collection>
</resultMap><select id="selectUserWithOrders" resultMap="userWithOrdersResultMap">SELECT u.id, u.name, o.id AS order_id, o.order_number, o.amountFROM User uLEFT JOIN Orders o ON u.id = o.user_idWHERE u.id = #{id}
</select>
这里使用 <collection> 标签定义了 User 对象中包含的 orders 集合。通过这个映射,MyBatis 会自动将查询到的 Order 记录映射到 User 对象的 orders 属性中。
四、多对多查询
多对多的关系通常通过中间表来表示,MyBatis 也可以处理这样的复杂关联。
示例:
假设 Student 表和 Course 表通过 Student_Course 中间表存在多对多关系。
<!-- 多对多映射 resultMap -->
<resultMap id="studentWithCoursesResultMap" type="com.example.Student"><id property="id" column="id"/><result property="name" column="name"/><collection property="courses" ofType="com.example.Course"><id property="id" column="course_id"/><result property="courseName" column="course_name"/></collection>
</resultMap><select id="selectStudentWithCourses" resultMap="studentWithCoursesResultMap">SELECT s.id, s.name, c.id AS course_id, c.course_nameFROM Student sLEFT JOIN Student_Course sc ON s.id = sc.student_idLEFT JOIN Course c ON sc.course_id = c.idWHERE s.id = #{id}
</select>
这里使用 <collection> 定义了 Student 对象中包含的 courses 集合。查询结果会自动映射到 Student 对象的 courses 属性中。
五、MyBatis 缓存机制
MyBatis 提供了两级缓存机制:
- 一级缓存(Local Cache):基于
SqlSession的缓存。一级缓存默认开启,且作用范围是SqlSession级别的。在同一个SqlSession中执行相同的 SQL 语句,MyBatis 会从缓存中取数据而不是再去查询数据库。 - 二级缓存(Global Cache):基于
mapper映射文件的缓存。作用范围是mapper映射文件级别,即同一个mapper中的多个SqlSession都可以共享该缓存。二级缓存需要手动配置开启。
一级缓存:
- 默认情况下一级缓存是开启的。
- 一级缓存的生效条件:同一个
SqlSession、相同的查询条件。
示例:
SqlSession session = sqlSessionFactory.openSession();
User user1 = session.selectOne("selectUser", 1); // 从数据库查询
User user2 = session.selectOne("selectUser", 1); // 从缓存中查询
二级缓存:
二级缓存需要在 mapper 映射文件中手动开启,且 Java 类必须实现序列化接口。
配置方式:
-
在 MyBatis 配置文件中开启二级缓存:
<settings><setting name="cacheEnabled" value="true"/> </settings> -
在
mapper文件中开启二级缓存:<cache/> -
Java 对象必须实现
Serializable接口,确保对象能被序列化并存入缓存。
二级缓存失效的条件:
- 执行了增删改操作,相关缓存会失效。
- 不同的
SqlSession。
六、MyBatis 相关常用知识点总结
- 动态 SQL:MyBatis 提供了
if、choose、when、foreach等标签来处理动态 SQL,满足多变的业务需求。 resultMap的使用:resultMap是 MyBatis 最强大的功能之一,它允许灵活地将查询结果映射到复杂的 Java 对象中。- 多数据源支持:MyBatis 支持多数据源的配置,可以方便地在项目中切换或同时操作多个数据库。
- 分页插件:MyBatis 本身不提供分页功能,但是可以通过插件(如
PageHelper)来实现数据库层面的分页操作。
七、综合案例
假设我们有三个表:User 表、Order 表和 Product 表。User 表与 Order 表是一对多的关系,Order 表与 Product 表是多对多的关系(通过 Order_Product 中间表实现)。我们希望查询用户、用户的订单以及每个订单中的产品信息。
数据库表设计:
User表:id、name。Order表:id、order_number、user_id。Product表:id、product_name。Order_Product表:order_id、product_id。
MyBatis 配置文件:
<!-- 综合案例 resultMap -->
<resultMap id="userWithOrdersAndProductsResultMap" type="com.example.User"><id property="id" column="id"/><result property="name" column="name"/><collection property="orders" ofType="com.example.Order"><id property="id" column="order_id"/><result property="orderNumber" column="order_number"/><collection property="products" ofType="com.example.Product"><id property="id" column="product_id"/><result property="productName" column="product_name"/></collection></collection>
</resultMap><select id="selectUserWithOrdersAndProducts" resultMap="userWithOrdersAndProductsResultMap">SELECT u.id, u.name, o.id AS order_id, o.order_number, p.id AS product_id, p.product_nameFROM User uLEFT JOIN Orders o ON u.id = o.user_idLEFT JOIN Order_Product op ON o.id = op.order_idLEFT JOIN Product p ON op.product_id = p.idWHERE u.id = #{id}
</select>
Java 类设计:
public class User implements Serializable {private Integer id;private String name;private List<Order> orders;// getters and setters
}public class Order implements Serializable {private Integer id;private String orderNumber;private List<Product> products;// getters and setters
}public class Product implements Serializable {private Integer id;private String productName;// getters and setters
}
通过以上配置和映射,当执行 selectUserWithOrdersAndProducts 查询时,MyBatis 会将用户、订单和订单中的产品信息自动映射到 User 对象及其关联的 Order 和 Product 对象中。
结语
MyBatis 在处理复杂的对象关系映射时提供了极大的灵活性。通过 resultMap 和缓存机制,我们能够有效地管理查询结果并提升系统性能。在实际开发中,掌握 MyBatis 的这些功能,可以更轻松地应对持久层的复杂逻辑。
相关文章:
MyBatis系统学习(四)——MyBatis的关联映射和缓存机制
MyBatis 是一个优秀的持久层框架,它通过 XML 或注解将 Java 对象与 SQL 语句相映射,简化了 JDBC 代码,增强了 SQL 的灵活性。在复杂业务场景中,数据库表之间经常存在一对一、一对多、多对多的关联关系,MyBatis 提供了相…...
【iOS】present和push
【iOS】present和push present和push的比较 present和push都用于iOS的视图切换,并且切换都是可逆的,原始视图不会被销毁,还可以直接更改window的rootViewController来切换视图,但是这种方法不可逆,并且原始视图会被销毁…...
Axure RP 9最新安装程序及汉化包下载(支持Win、Mac版,附下载安装教程)
数月前Axure RP官方已经发布了Axure RP 9的消息,并计划在今年夏天发布beta版本。新版Axure RP 9将是该工具向前迈出的重要一步,其中包括一系列广泛的改进:全面的UI修改,新的设计和文档功能以及前所未有的内部优化。我们已经彻底重…...
k8s环境搭建(续)
查看节点信息并做快照 kubectl get nodes 将components.yml文件上传到master主机 创建nginx,会在添加一个新的pod kubectl run nginx --imagesnginx:latest 查看nginx的pod信息 [rootk8s-master ~]# kubectl get po -Aowide|grep nginx 出现错误,查…...
kali——binwalk的使用
目录 前言 使用方法 分析文件 分离文件 前言 binwalk是一个用于分析、逆向工程和提取固件映像的工具。 binwalk能够分析固件映像文件,识别其中包含的文件。例如,它可以从一个设备固件中提取出压缩文件或图片等嵌入内容。 使用方法 分析文件 binwa…...
Ubuntu 24.04中安装virtualenv
在Ubuntu 24.04中安装virtualenv,可以按照以下步骤进行: 1. 确保Python已安装: 在终端中输入python --version或python3 --version来检查Python的安装情况。 python3 --version2. 安装pip(如果尚未安装)&#x…...
一个简约的uniapp登录界面,基于uniapp+vue3+uview-plus
uniapp-vue3-template 一个简约的uniapp登录界面,基于uniappvue3uview-plus 页面主要包括:用户登录,手机验证码登录,用户注册,重置密码等页面 登录进去后为空白模板 源码在文末 界面 源码 uniapp登录界面源码...
系统架构设计师 需求分析篇二
📘 面向对象分析方法 1. 用例模型 📈 构建用例模型一般需要经历 4 个阶段: 识别参与者 🔍:识别与系统交互的所有事物。合并需求获得用例 🔗:将需求分配给予其相关的参与者。细化用例描述 &am…...
IP 协议分析《实验报告》
目录 一、 实验目的 二、实验设备和环境 三、实验记录 1、实验环境搭建 2、IP 协议分析 1.设置抓包接口 2.IP 报文分析 3.报文长度计算 4.生存时间 TTL 5.分析总结 3、IP分片 1.IP 分片简介 2.捕获分组 3.结果分析 一、 实验目的 1、掌握 IP 协议数据报格式&…...
人工智能开发实战matplotlib库应用基础
内容导读 matplotlib简介绘制直方图绘制撒点图 一、matplotlib简介 matplotlib是一个Python 2D绘图库,它以多种硬拷贝格式和跨平台的交互式环境生成高质量的图形。 matplotlib 尝试使容易的事情变得更容易,使困难的事情变得可能。 我们只需几行代码…...
Android 源码集成可卸载 APP
android系统包含三类APP: 1、可自由卸载APP安装在 /data/app目录下。 2、系统APP放在 /system/app目录。 3、特权APP放在 /system/priv-app目录。 系统编译后,打包前, /data分区不起作用,因此系统打包前,可以先将APP全部拷贝到 /…...
cJSON-轻量级解析模块、字符串的神——编织STM32C8T6与阿里云信息传递的纽带
编写方向:本人就不泛泛的编写一篇什么一文学会cJSON了,没什么突出点,也就我水水字数,你们看来看去也不懂,本人是从上阿里云传信息接触的cJSON的,我就此写一篇针对性的文章,希望对大家有用&#…...
【Git】Clone
当git clone失败时,出现 RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: CANCEL (err 8) 错误,可能由于网络连接不稳定或仓库太大导致的。 可以尝试以下几种方法来解决这个问题: 增加 Git 的缓冲区大小: git confi…...
web开发 之 HTML、CSS、JavaScript、以及JavaScript的高级框架Vue(学习版2)
一、前言 接下来就是来解决这些问题 二、 Ajax 1.ajax javscript是网页三剑客之一,空用来控制网页的行为的 xml是一种标记语言,是用来存储数据的 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-…...
【课程学习】信号检测与估计II
b站 文章目录 1-概述 1-概述 线性、正交、平稳、高斯 研究线性模型,采用正交化方法,假设信号平稳,考虑信号的统计特性是高斯的。 本学期考虑,非线性、非正交、非平稳、非高斯。 阵列处理 1980-1990 MUSIC 稀疏性 2006-2012 LASS 时…...
【深度学习|PyTorch】基于 PyTorch 搭建 U-Net 深度学习语义分割模型——附代码及其解释!
【深度学习|PyTorch】基于 PyTorch 搭建 U-Net 深度学习语义分割模型——附代码及其解释! 【深度学习|PyTorch】基于 PyTorch 搭建 U-Net 深度学习语义分割模型——附代码及其解释! 论文地址: https://arxiv.org/abs/1505.04597 代码地址&a…...
DPDK基础入门(十):虚拟化
I/O虚拟化 全虚拟化:宿主机截获客户机对I/O设备的访问请求,然后通过软件模拟真实的硬件。这种方式对客户机而言非常透明,无需考虑底层硬件的情况,不需要修改操作系统。 半虚拟化:通过前端驱动/后端驱动模拟实现I/O虚拟…...
OpenCV_图像旋转超详细讲解
图像转置 transpose(src, dst); transpose()可以实现像素下标的x和y轴坐标进行对调:dst(i,j)src(j,i),接口形式 transpose(InputArray src, // 输入图像OutputArray dst, // 输出 ) 图像翻转 flip(src, dst, 1); flip()函数可以实现对图像的水平翻转…...
关于 OceanBase 4.x 中被truncate的 table 不再支持进回收站的原因
近期,OceanBase的问答社区中收到了不少用户的询问,关于OceanBase 3.x版本支持被truncate的table进入回收站的功能,为何在升级到4.x版本后不再支持了?为了解答大家的疑惑,我们将通过这篇文章来浅析 OceanBase在4.x版本中…...
Numpy索引详解(数值索引,列表索引,布尔索引)
数值索引 数值索引类似列表索引操作使用[],参数为下标,[0,len-1),高维数组的索引使用多个[]连用分别代表一维索引,二维索引... import numpy as np import torchnp.random.seed(1) data1 np.arange(5) data2 np.arange(15).reshape(3,5) …...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
MLP实战二:MLP 实现图像数字多分类
任务 实战(二):MLP 实现图像多分类 基于 mnist 数据集,建立 mlp 模型,实现 0-9 数字的十分类 task: 1、实现 mnist 数据载入,可视化图形数字; 2、完成数据预处理:图像数据维度转换与…...
【Zephyr 系列 16】构建 BLE + LoRa 协同通信系统:网关转发与混合调度实战
🧠关键词:Zephyr、BLE、LoRa、混合通信、事件驱动、网关中继、低功耗调度 📌面向读者:希望将 BLE 和 LoRa 结合应用于资产追踪、环境监测、远程数据采集等场景的开发者 📊篇幅预计:5300+ 字 🧭 背景与需求 在许多 IoT 项目中,单一通信方式往往难以兼顾近场数据采集…...
ABB馈线保护 REJ601 BD446NN1XG
配电网基本量程数字继电器 REJ601是一种专用馈线保护继电器,用于保护一次和二次配电网络中的公用事业和工业电力系统。该继电器在一个单元中提供了保护和监控功能的优化组合,具有同类产品中最佳的性能和可用性。 REJ601是一种专用馈线保护继电器…...
