MyBatis如何处理延迟加载?

news2025/1/6 5:33:10

大家好,我是锋哥。今天分享关于【MyBatis如何处理延迟加载?】面试题。希望对大家有帮助;

MyBatis如何处理延迟加载?

1000道 互联网大厂Java工程师 精选面试题-Java资源分享网

在 MyBatis 中,延迟加载(Lazy Loading) 是指在访问某个对象的属性时,才去加载与该属性相关的关联数据,而不是在查询主对象时就加载所有相关的数据。这样可以提高性能,避免不必要的数据加载,尤其是在处理大型数据集时。

MyBatis 提供了两种延迟加载的方式:延迟加载属性延迟加载关联对象。下面详细介绍如何配置和使用这两种方式。

1. 延迟加载的基本原理

在 MyBatis 中,延迟加载通常涉及 一对一一对多 的关联关系。在默认情况下,MyBatis 会一次性加载所有相关联的数据。而启用延迟加载后,只有在访问关联数据时才会查询数据库。

2. 延迟加载配置

2.1 全局配置延迟加载

可以通过 MyBatis 的全局配置启用延迟加载功能。你需要在 mybatis-config.xml 配置文件中添加以下配置:

<configuration>
    <settings>
        <!-- 启用延迟加载 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 启用全局的延迟加载(即对所有关联属性进行延迟加载) -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
</configuration>
  • lazyLoadingEnabled:启用延迟加载功能,默认值是 false,即不启用延迟加载。
  • aggressiveLazyLoading:决定是否在加载主对象时强制加载所有懒加载的属性。如果设置为 true,即使懒加载属性没有被访问,也会提前加载。
2.2 延迟加载关联属性

在映射文件中,你可以使用 fetchType 属性来控制延迟加载的行为。MyBatis 提供了两种加载方式:

  • EAGER(立即加载):即在查询主对象时,一并加载相关的属性。
  • LAZY(延迟加载):只有在访问相关属性时,才会触发数据库查询。

通常是在关联映射的 <association><collection> 标签上进行设置。

<resultMap id="userResultMap" type="User">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <!-- 延迟加载关联对象 -->
    <association property="profile" column="profile_id" 
                 javaType="Profile" 
                 fetchType="lazy"/>
</resultMap>

在这个例子中,profile 这个属性使用了延迟加载,只有在访问 user.getProfile() 时,才会从数据库加载 Profile 数据。

2.3 延迟加载集合属性

如果是集合类型的属性(如一对多关系),可以使用 <collection> 标签进行延迟加载配置。

<resultMap id="authorResultMap" type="Author">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <!-- 延迟加载书籍集合 -->
    <collection property="books" ofType="Book" 
                column="author_id" 
                fetchType="lazy"/>
</resultMap>

这里,booksAuthor 类的一个集合属性,它表示这个作者的所有书籍。只有在访问 author.getBooks() 时,才会从数据库加载书籍数据。

3. 延迟加载与会话管理

MyBatis 的延迟加载是基于 SqlSession 管理的,因此你需要确保在访问懒加载属性时,SqlSession 依然处于有效状态。通常情况下,延迟加载是在同一个 SqlSession 中进行的。如果 SqlSession 被关闭或提交后,再访问懒加载的属性时会抛出异常。

示例:
SqlSession session = sqlSessionFactory.openSession();
User user = session.selectOne("selectUserById", 1);
session.close();

// 延迟加载将在这里触发
Profile profile = user.getProfile();

在这个例子中,getProfile() 方法会在懒加载时触发数据库查询,因此必须在 SqlSession 还没有关闭之前访问它。

4. 延迟加载的性能考量

虽然延迟加载可以减少不必要的数据加载,但是滥用延迟加载也可能导致性能问题,例如产生 N+1 查询问题,即如果你查询一个列表对象并逐个懒加载关联属性,那么会发送大量的 SQL 查询请求。

4.1 N+1 查询问题

当你查询一个包含懒加载关联属性的对象集合时,每次访问懒加载属性时都可能会执行一次查询,导致 SQL 查询次数增加。例如:

List<User> users = session.selectList("selectAllUsers");
for (User user : users) {
    // 每次访问 user.getProfile() 都会发起一个额外的查询
    Profile profile = user.getProfile();
}

解决这个问题的一个办法是使用 批量查询 或者通过 嵌套查询 来减少查询次数。

4.2 批量查询

MyBatis 提供了 @Many 注解(如果使用注解配置)来解决这一问题。例如,使用嵌套查询加载关联对象:

<resultMap id="userResultMap" type="User">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <association property="profile" column="profile_id" 
                 javaType="Profile" 
                 select="selectProfileById"/>
</resultMap>

在这种情况下,selectProfileById 会在加载 User 对象时一起加载 Profile 数据,从而避免了多个查询。

5. 总结

MyBatis 的延迟加载机制允许开发者根据实际需要控制关联对象的加载时机,从而提升性能。通过配置全局设置或使用 fetchType="lazy" 配置,可以有效地延迟加载关联数据。然而,延迟加载也可能带来性能问题(如 N+1 查询问题),需要在实际应用中仔细权衡和优化。

  • 开启延迟加载:通过 lazyLoadingEnabled 和 fetchType="lazy" 进行配置。
  • 管理会话:确保在同一个 SqlSession 中访问懒加载属性。
  • 优化查询:避免 N+1 查询问题,可以使用嵌套查询或批量查询来减少查询次数。

使用延迟加载时,合理规划数据库查询,确保性能最优。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2271268.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ELK 使用教程采集系统日志 Elasticsearch、Logstash、Kibana

前言 你知道对于一个系统的上线考察&#xff0c;必备的几样东西是什么吗&#xff1f;其实这也是面试中考察求职者&#xff0c;是否真的做过系统开发和上线的必备问题。包括&#xff1a;服务治理(熔断/限流) (opens new window)、监控 (opens new window)和日志&#xff0c;如果…

重庆市大数据局:基于可信数据空间的公共数据流通利用

在2024年可信数据空间论坛上&#xff0c;重庆市大数据局相关领导发表了题为&#xff1a;基于可信数据空间的公共数据流通利用的演讲&#xff0c;系统介绍了重庆公共数据流通方面的实践经验和案例。 篇幅限制&#xff0c;部分内容如下&#xff1a;

Sublime Text4 4189 安装激活【 2025年1月3日 亲测可用】

-----------------测试时间2025年1月3日------------------- 下载地址 官方网址&#xff1a;https://www.sublimetext.com 更新日志&#xff1a;https://www.sublimetext.com/download V4189 64位&#xff1a;https://www.sublimetext.com/download_thanks?targetwin-x64 ....…

LabVIEW开发中常见硬件通讯接口快速识别

在 LabVIEW 开发中&#xff0c;与硬件进行通讯是实现数据采集与控制的重要环节。准确判断通讯接口类型和协议&#xff0c;可以提高开发效率&#xff0c;减少调试时间。本文结合 LabVIEW 的实际应用&#xff0c;详细介绍如何识别和判断常见硬件通讯接口的定义&#xff0c;并提供…

刷机TP TP-Link-WDR5660【持续更新】

上文中简单介绍了&#xff1a;路由器刷机TP-Link tp-link-WDR5660 路由器升级宽带速度-CSDN博客 步骤如下&#xff1a; 第一步&#xff1a;安装Linux系统 本文使用virtualBox 安装Ubuntu的debian系统&#xff0c;本文不在讲述章 请自行参考&#xff1a;Kali 安装之腾讯云经验…

Linux-Redis哨兵搭建

环境资源准备 主机名IP端口号角色vm1192.168.64.156379/26379mastervm2192.168.64.166379/26379slavevm3192.168.64.176379/26379slave 6379为redis服务暴露端口号、26379为sentinel暴露端口号。 安装Redis # 包文件下载 wget https://github.com/redis/redis/archive/7.2.2…

df.groupby()方法使用表达式分组

# 索引值是否为偶数&#xff0c;分成两组 df.groupby(lambda x:x%20).sum() df.groupby(df.index%20).sum() # 同上这两个写法看似相似&#xff0c;确实都基于索引值来进行分组&#xff0c;但在实现方式上有细微的区别&#xff1a; df.groupby(lambda x: x % 2 0) 这种方式通过…

Python 数据可视化的完整指南

目录 一、为什么选择 Python 进行数据可视化? 二、常用 Python 可视化库及其特点 三、常用图表类型及其代码示例 折线图:用于展示数据随时间或其他连续变量的变化趋势。 柱状图:用于比较不同类别的数据大小。 散点图:用于展示两个变量之间的关系,并发现数据中的模式…

国内Ubuntu环境Docker部署CosyVoice

国内Ubuntu环境Docker部署CosyVoice 本文旨在记录在 国内 CosyVoice项目在 Ubuntu 环境下如何使用 dockermin-conda进行一键部署。 源项目地址&#xff1a; https://github.com/FunAudioLLM/CosyVoice 如果想要使用 dockerpython 进行部署&#xff0c;可以参考我另一篇博客中的…

Git的使用流程(详细教程)

目录 01.Git是什么&#xff1f; 1.1 Git简介 1.2 SVN与Git的最主要的区别 1.3 GIt主要特点 02.Git是干什么的&#xff1f; 2.1.Git概念汇总 2.2 工作区/暂存区/仓库 2.3 Git使用流程 03.Git的安装配置 3.1 Git的配置文件 3.2 配置-初始化用户 3.3 Git可视化…

ImageNet 2.0?自动驾驶数据集迎来自动标注新时代

引言&#xff1a; 3DGS因其渲染速度快和高质量的新视角合成而备受关注。一些研究人员尝试将3DGS应用于驾驶场景的重建。然而&#xff0c;这些方法通常依赖于多种数据类型&#xff0c;如深度图、3D框和移动物体的轨迹。此外&#xff0c;合成图像缺乏标注也限制了其在下游任务中的…

npm install --global windows-build-tools --save 失败

注意以下点 为啥下载windows-build-tools&#xff0c;是因为node-sass4.14.1 一直下载不成功&#xff0c;提示python2 没有安装&#xff0c;最终要安装这个&#xff0c;但是安装这个又失败&#xff0c;主要有以下几个要注意的 1、node 版本 14.21.3 不能太高 2、管理员运行 …

Beamer-LaTeX学习(教程批注版)【1】

该文档总体由beamer-latex的教程而来&#xff0c;由耳东小白以自身学习路径整理。因其中要点基本按照教程的顺序和结构整理&#xff0c;故而不能称之为完全原创&#xff0c;但也不是翻译&#xff0c;更不是抄袭&#xff0c;是个人自学笔记和批注&#xff0c;其中添加了小白个人…

wx005基于springboot+vue+uniapp的大学生心理健康测评管理系统小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

SpringBoot整合springmvc、扩展springmvc

目录 一、 SpringMVC三大组件二、 Spring MVC 组件的自动管理2.1 中央转发器&#xff08;DispatcherServlet&#xff09;2.2 控制器2.3 视图解析器自动管理2.4 静态资源访问2.5 消息转换和格式化2.6 欢迎页面的自动配置 三、Springboot扩展springmvc3.1 视图控制器注册&#xf…

STM32使用UART发送字符串与printf输出重定向

首先我们先看STM32F103C8T6的电路图 由图可知&#xff0c;其PA9和PA10引脚分别为UART的TX和RX(注意&#xff1a;这个电路图是错误的&#xff0c;应该是PA9是X而PA9是RX&#xff0c;我们看下图的官方文件可以看出)&#xff0c;那么接下来我们应该找到该引脚的定义是什么&#xf…

力扣28找出字符串中第一个匹配项的下标

class Solution:def strStr(self, haystack: str, needle: str) -> int:# 特殊情况处理if not needle:return 0# 获取 haystack 和 needle 的长度a len(needle)b len(haystack)# 遍历 haystack&#xff0c;检查每个子字符串是否与 needle 匹配for i in range(b - a 1):if…

8、RAG论文笔记(Retrieval-Augmented Generation检索增强生成)

RAG论文笔记 1、 **研究背景与动机**2、方法概述3、RAG 模型架构3.1总体架构3.2 Generator&#xff08;生成器&#xff09;3.3 检索器&#xff08;Retriever&#xff09;3.4训练&#xff08;Training&#xff09;3.5**解码方法**&#xff08;求近似 &#xff09;3.6微调的参数 …

PCA降维算法详细推导

关于一个小小的PCA的推导 文章目录 关于一个小小的PCA的推导1 谱分解 (spectral decomposition)2 奇异矩阵(singular matrix)3 酉相似(unitary similarity)4 酉矩阵5 共轭变换6 酉等价7 矩阵的迹的计算以及PCA算法推导8 幂等矩阵(idempotent matrix)9 Von Neumanns 迹不等式 [w…

Android studio 旧版本下载,NDK旧版本下载

记录一下旧版的ndk 和 Android studio 官方下载备份。 1.NDK 旧版本下载地址 下载地址&#xff1a;https://github.com/android/ndk/wiki/Unsupported-Downloads 2.Android studio 旧版本下载 下载地址 https://developer.android.com/studio/archive 如果出现以下页面 点击…