面试笔记——MyBatis(执行流程、延迟加载和缓存)

news/2024/4/26 23:21:40/文章来源:https://blog.csdn.net/Z__XY_/article/details/137014240

MyBatis 是一个持久层框架,用于简化 Java 应用程序与数据库之间的交互过程。具体而言,它提供了一种将数据库操作映射到 Java 方法的方式,通过 XML 文件或注解配置 SQL 语句与 Java 方法的映射关系。使用 MyBatis,开发人员可以通过简单的配置文件或注解来管理 SQL 语句,而不需要直接编写 JDBC 代码。

MyBatis的执行流程

流程图如下:
在这里插入图片描述

  1. 读取MyBatis配置文件,如mybatis-config.xml(该文件包含了 MyBatis 的全局配置信息,如数据库连接信息、缓存配置、映射文件的路径等)加载运行环境;映射文件,如XxxMapper,xml(该文件包含了 SQL 语句与 Java 方法的映射关系,以及结果映射等配置)。
  2. 构造会话工厂SqlSessionFactory, 它是 MyBatis 的核心接口之一,它负责创建 SqlSession 对象,SqlSession 是 MyBatis 中执行 SQL 的主要接口。
  3. 会话工厂创建SqlSession对象(包含了执行SQL语句的所有方法),它SqlSession 提供了执行 SQL 语句、获取映射器(Mapper)等功能。
  4. 操作数据库的接口,Executor执行器,同时负责查询缓存的维护,通过 SqlSession 执行 SQL 语句,可以是预定义的 SQL 语句,也可以是动态生成的 SQL 语句。
  5. Executor接口的执行方法中有一个MappedStatement类型的参数,封装了映射信息,因此,MyBatis 会根据 SQL 语句的配置,进行参数绑定、结果映射等操作。
  6. 关闭 SqlSession,在完成数据库操作后,应用程序需要关闭 SqlSession,释放数据库连接等资源。通常情况下,可以通过 try-with-resources 或手动调用 close() 方法来关闭 SqlSession。

MyBatis的延迟加载

延迟加载(Lazy Loading) 是一种软件设计模式,用于推迟对象或数据的加载直到真正需要使用它们的时候。在软件开发中,延迟加载通常用于优化性能和资源利用,避免不必要的开销和提高用户体验。

在数据库访问中,延迟加载通常指的是将某些数据的加载推迟到需要访问这些数据的时候才进行,而不是在查询时立即加载所有数据。这样做可以减少数据库查询次数,降低系统负载,提高性能。延迟加载通常应用于复杂对象关系的情况,其中某些关联数据不一定需要在每次查询中都被加载,而是根据需要进行加载。

例如:
在这里插入图片描述
Mybatis支持延迟记载,但默认是关闭的,可以在MyBartis的配置文件中,通过lazyLoadingEnabled=true|false进行设置。

MyBatis 支持两种类型的延迟加载:

  1. 关联对象延迟加载

    • 当一个对象关联了其他对象(一对一、一对多等关系),并且配置为延迟加载时,MyBatis 会在访问该关联对象时才真正执行相关的查询操作,将关联对象加载到内存中。
  2. 集合延迟加载

    • 当一个对象关联了一个集合对象(一对多关系),并且配置为延迟加载时,MyBatis 会在访问该集合对象时才真正执行相关的查询操作,将集合加载到内存中。

延迟加载的实现原理通常是使用代理对象,在对象的属性被访问时触发数据库查询。它的配置通常在 MyBatis 映射文件(XxxMapper.xml)中进行,可以通过以下方式实现延迟加载:

<association property="associationProperty" select="selectStatement" fetchType="lazy" />
<collection property="collectionProperty" select="selectStatement" fetchType="lazy" />

其中,associationcollection 标签用于指定延迟加载的对象或集合,select 属性指定了延迟加载时执行的查询语句,fetchType="lazy" 则指定了延迟加载的方式为懒加载。
需要注意的是,延迟加载必须依赖于外部事务或连接,因此在延迟加载期间,相关的数据库连接必须保持打开状态。在使用延迟加载时,开发人员需要谨慎处理事务的管理,以避免可能的资源泄露或数据不一致。

延迟加载的原理:

  1. 使用CGLIB创建目标对象的代理对象
  2. 当调用目标方法user.getOrderList()时,进入拦截器invoke方法,发现user.getOrderList()是null值,执行sql查询order列表
  3. 获取到数据后,然后调用user.setOrderList(List orderList) ,接着完成user.getOrderList()方法的调用

在这里插入图片描述

MyBatis的缓存

MyBatis 提供了一级缓存和二级缓存两种缓存机制,用于提高数据库访问性能。这些缓存可以在适当的情况下存储已经查询过的数据,以避免重复查询数据库,提高系统性能。

一级缓存是 MyBatis 默认开启的,它是基于 SqlSession 对象的缓存,也就是说,只有在同一个 SqlSession 内执行的查询可以共享一级缓存。一级缓存存储在 SqlSession 的生命周期内,当调用 commit()close()clearCache() 等方法时会清空一级缓存。

一级缓存的特点包括:

  • 作用范围:只在当前 SqlSession 内有效,不同的 SqlSession 之间不共享缓存。
  • 生命周期:与 SqlSession 的生命周期一致,当 SqlSession 关闭时缓存也会失效。
  • 自动管理:MyBatis 会自动管理一级缓存,无需手动配置。

二级缓存是一个跨 SqlSession 的缓存,它可以被多个 SqlSession 共享,即它的作用域是namespace和mapper的作用域,不依赖于session。当多个 SqlSession 查询相同的数据时,如果开启了二级缓存,则第一个查询结果会被缓存起来,后续的查询可以直接从缓存中获取数据,而不需要再次查询数据库。

二级缓存的特点包括:

  • 作用范围:跨 SqlSession,可以被多个 SqlSession 共享。
  • 生命周期:缓存在整个应用程序的生命周期内有效,需要手动配置并在需要时开启。
  • 需要序列化支持:由于二级缓存需要跨 SqlSession 进程共享数据,因此缓存的数据需要支持序列化。

配置二级缓存:

  1. 在 MyBatis 的配置文件中开启二级缓存:

    <settings><setting name="cacheEnabled" value="true"/>
    <\settings>
    
  2. 映射文件中配置需要使用二级缓存的语句:

    <mapper namespace="com.example.mapper.UserMapper"><cache/><!-- 或者在具体的 select 语句上添加 <cache/> 标签 -->
    </mapper>
    

MyBatis 的缓存机制能够有效地提高数据库访问性能,一级缓存适用于单个 SqlSession 内的缓存需求,而二级缓存适用于多个 SqlSession 之间共享数据的缓存需求。

注意:

  1. 对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了新增、修改、删除操作后,默认该作用域下所有 select 中的缓存将被 clear
  2. 二级缓存需要缓存的数据实现Serializable接口
  3. 只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOV8逐步分解(2)_DetectionTrainer类初始化过程

接上篇文章yolov8逐步分解(1)--默认参数&超参配置文件加载继续讲解。 1. 默认配置文件加载完成后&#xff0c;创建对象trainer时&#xff0c;需要从默认配置中获取类DetectionTrainer初始化所需的参数args&#xff0c;如下所示 def train(cfgDEFAULT_CFG, use_pythonFalse…

Docker-Container

Docker ①什么是容器②为什么需要容器③容器的生命周期容器 OOM容器异常退出容器暂停 ④容器命令清单总览docker createdocker rundocker psdocker logsdocker attachdocker execdocker startdocker stopdocker restartdocker killdocker topdocker statsdocker container insp…

Elasticsearch从入门到精通-07ES底层原理学习

Elasticsearch从入门到精通-07ES底层原理和高级功能 &#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是程序员行走的鱼 &#x1f4d6; 本篇主要介绍和大家一块学习一下ES底层原理包括集群原理、路由原理、分配控制、分配原理、文档分析原理、文档并发安全原理以及一些高…

第十四届蓝桥杯JavaA组省赛真题 - 特殊日期

解题思路&#xff1a; 暴力秒了 public class Main {public static void main(String[] args) {int cnt 0;for (int i 1900; i < 9999; i) {for (int j 1; j < 12; j) {for (int k 1; k < days(i, j); k) {if (sum(i) sum(j) sum(k)) cnt;}}}System.out.print…

算法笔记~—位运算

目录 常见位运算&#xff1a; 1、基础位运算 2、对于一个数n。确定、修改这个数n二进制x位。 3、提取&#xff08;确定&#xff09;一个数n最右侧的1&#xff08;bit&#xff09;与干掉最右侧的1&#xff08;bit&#xff09; 4、异或运算律 5、位运算的优先级&#xff1a…

Qt扫盲-QAssisant 集成其他qch帮助文档

QAssisant 集成其他qch帮助文档 一、概述二、Cmake qch例子1. 下载 Cmake.qch2. 添加qch1. 直接放置于Qt 帮助的目录下2. 在 QAssisant中添加 一、概述 QAssisant是一个很好的帮助文档&#xff0c;他提供了供我们在外部添加新的 qch帮助文档的功能接口&#xff0c;一般有两中添…

百度智能云千帆,产业创新新引擎

本文整理自 3 月 21 日百度副总裁谢广军的主题演讲《百度智能云千帆&#xff0c;产业创新新引擎》。 各位领导、来宾、媒体朋友们&#xff0c;大家上午好。很高兴今天在石景山首钢园&#xff0c;和大家一起沟通和探讨大模型的发展趋势&#xff0c;以及百度最近一段时间的思考和…

为什么Python不适合写游戏?

知乎上有热门个问题&#xff1a;Python 能写游戏吗&#xff1f;有没有什么开源项目&#xff1f; Python可以开发游戏&#xff0c;但不是好的选择 Python作为脚本语言&#xff0c;一般很少用来开发游戏&#xff0c;但也有不少大型游戏有Python的身影&#xff0c;比如&#xff1…

sheng的学习笔记-AI-人脸识别

目录:sheng的学习笔记-AI目录-CSDN博客 需要学习卷机神经网络等知识&#xff0c;见ai目录 目录 基础知识&#xff1a; 人脸验证&#xff08;face verification&#xff09; 人脸识别&#xff08;face recognition&#xff09; One-Shot学习&#xff08;One-shot learning&…

PTA-练习8

目录 实验5-3 使用函数求Fibonacci数 实验5-4 输出每个月的天数 实验5-9 使用函数求余弦函数的近似值 实验5-11 空心的数字金字塔 实验6-6 使用函数验证哥德巴赫猜想 实验6-7 使用函数输出一个整数的逆序数 实验6-8 使用函数输出指定范围内的完数 实验8-1-7 数组循环右…

Transformer的前世今生 day11(Transformer的流程)

Transformer的流程 在机器翻译任务中&#xff0c;翻译第一个词&#xff0c;Transformer的流程为&#xff1a; 先将要翻译的句子&#xff0c;一个词一个词的转换为词向量送入编码器层&#xff0c;得到优化过的词向量以及K、V&#xff0c;将K、V送入解码器层&#xff0c;并跟解码…

halcon例程学习——ball.hdev

dev_update_window (off) dev_close_window () dev_open_window (0, 0, 728, 512, black, WindowID) read_image (Bond, die/die_03) dev_display (Bond) set_display_font (WindowID, 14, mono, true, false) *自带的 提示继续 disp_continue_message (WindowID, black, true)…

android studio忽略文件

右键文件&#xff0c;然后忽略&#xff0c;就不会出现在commit里面了 然后提交忽略文件即可

Vue3 + Vite + TS + Element-Plus + Pinia项目(5)对axios进行封装

1、在src文件夹下新建config文件夹后&#xff0c;新建baseURL.ts文件&#xff0c;用来配置http主链接 2、在src文件夹下新建http文件夹后&#xff0c;新建request.ts文件&#xff0c;内容如下 import axios from "axios" import { ElMessage } from element-plus im…

【C++的奇迹之旅】C++关键字命名空间使用的三种方式C++输入输出命名空间std的使用惯例

文章目录 &#x1f4dd;前言&#x1f320; C关键字(C98)&#x1f309; 命名空间&#x1f320;命名空间定义&#x1f309;命名空间使用 &#x1f320;命名空间的使用有三种方式&#xff1a;&#x1f309;加命名空间名称及作用域限定符&#x1f320;使用using将命名空间中某个成员…

【JVM】Java类加载器 和 双亲委派机制

1、java类加载器的分类 JDK8及之前 启动类加载器&#xff0c;BootStrap Class Loader,加载核心类,加载jre/lib目录下的类&#xff0c;C实现的拓展类加载器&#xff0c; Extension Class Loader&#xff0c;加载java拓展类库&#xff0c;jre/lib/ext目录下&#xff0c;比如javax…

蓝桥杯 java 凑算式 16年省赛Java组真题

题目 思路&#xff1a; 求有多少种解法 比如:68/3952/714就是一种解法&#xff0c;53/1972/486 是另一种解法 8/3952/714是可以除尽的 但是后面一个不行 所以我们也要通分 代码&#xff1a; public class 凑算式 {static int[] a {1, 2, 3, 4, 5, 6, 7, 8, 9};static int c…

SpringBoot Redis的使用

官方文档&#xff1a; 官方文档&#xff1a;Spring Data Redis :: Spring Data Redis 和jedis一样&#xff0c;SpringBoot Redis 也可以让我在Java代码中使用redis&#xff0c;同样也是通过引入maven依赖的形式。 加速访问github: 使用steam可以免费加速访问github Spring…

鸿蒙OS开发实例:【页面传值跳转】

介绍 本篇主要介绍如何在HarmonyOS中&#xff0c;在页面跳转之间如何传值 HarmonyOS 的页面指的是带有Entry装饰器的文件&#xff0c;其不能独自存在&#xff0c;必须依赖UIAbility这样的组件容器 如下是官方关于State模型开发模式下的应用包结构示意图&#xff0c;Page就是…

设计模式之单例模式精讲

UML图&#xff1a; 静态私有变量&#xff08;即常量&#xff09;保存单例对象&#xff0c;防止使用过程中重新赋值&#xff0c;破坏单例。私有化构造方法&#xff0c;防止外部创建新的对象&#xff0c;破坏单例。静态公共getInstance方法&#xff0c;作为唯一获取单例对象的入口…