Spring 整合 MyBatis 底层源码解析
大家好,我是柳岸花开。今天我们要讲的是 Spring 整合 MyBatis 的底层源码解析。希望大家能更深入理解 Spring 和 MyBatis 的整合原理,并应用到实际项目中。
由很多框架都需要和Spring进行整合,而整合的核心思想就是把其他框架所产生的对象放到Spring容器中,让其成为Bean。
Mybatis框架可以单独使用,而单独使用Mybatis框架就需要用到Mybatis所提供的一些类构造出对应的对象,然后使用该对象,就能使用到Mybatis框架给我们提供的功能,和Mybatis整合Spring就是为了将这些对象放入Spring容器中成为Bean,只要成为了Bean,在我们的Spring项目中就能很方便的使用这些对象了,也就能很方便的使用Mybatis框架所提供的功能了。
一、Spring 和 MyBatis 简介
Spring:
-
一个开源框架,提供全面的基础设施支持,简化 Java 开发,特别是在企业级开发中。 -
核心是控制反转(IoC)和面向切面编程(AOP)。
MyBatis:
-
优秀的持久层框架,支持自定义 SQL、存储过程及高级映射。 -
避免了大部分 JDBC 代码和手动设置参数及获取结果集的麻烦。
Mybatis-Spring底层源码执行流程
-
通过@MapperScan导入了MapperScannerRegistrar类 -
MapperScannerRegistrar类实现了ImportBeanDefinitionRegistrar接口,所以Spring在启动时会调用MapperScannerRegistrar类中的registerBeanDefinitions方法 -
在registerBeanDefinitions方法中注册一个MapperScannerConfigurer类型的BeanDefinition -
而MapperScannerConfigurer实现了BeanDefinitionRegistryPostProcessor接口,所以Spring在启动过程中时会调用它的postProcessBeanDefinitionRegistry()方法 -
在postProcessBeanDefinitionRegistry方法中会生成一个ClassPathMapperScanner对象,然后进行扫描 -
设置ClassPathMapperScanner对象可以扫描到接口,因为在Spring中是不会扫描接口的 -
同时因为ClassPathMapperScanner中重写了isCandidateComponent方法,导致isCandidateComponent只会认为接口是备选者Component -
通过利用Spring的扫描后,会把接口扫描出来并且得到对应的BeanDefinition -
接下来把扫描得到的BeanDefinition进行修改,把BeanClass修改为MapperFactoryBean,把AutowireMode修改为byType -
扫描完成后,Spring就会基于BeanDefinition去创建Bean了,相当于每个Mapper对应一个FactoryBean -
在MapperFactoryBean中的getObject方法中,调用了getSqlSession()去得到一个sqlSession对象,然后根据对应的Mapper接口生成一个Mapper接口代理对象,这个代理对象就成为Spring容器中的Bean -
sqlSession对象是Mybatis中的,一个sqlSession对象需要SqlSessionFactory来产生 -
MapperFactoryBean的AutowireMode为byType,所以Spring会自动调用set方法,有两个set方法,一个setSqlSessionFactory,一个setSqlSessionTemplate,而这两个方法执行的前提是根据方法参数类型能找到对应的bean,所以Spring容器中要存在SqlSessionFactory类型的bean或者SqlSessionTemplate类型的bean。 -
如果你定义的是一个SqlSessionFactory类型的bean,那么最终也会被包装为一个SqlSessionTemplate对象,并且赋值给sqlSession属性 -
而在SqlSessionTemplate类中就存在一个getMapper方法,这个方法中就产生一个Mapper接口代理对象 -
到时候,当执行该代理对象的某个方法时,就会进入到Mybatis框架的底层执行流程。
Spring整合Mybatis后一级缓存失效问题
Mybatis中的一级缓存是基于SqlSession来实现的,所以在执行同一个sql时,如果使用的是同一个SqlSession对象,那么就能利用到一级缓存,提高sql的执行效率。
在Spring整合Mybatis后,如果执行某个方法时,该方法上没有加@Transactional注解,也就是没有开启Spring事务,那么后面在执行具体sql时,每执行一个sql时都会新生成一个SqlSession对象来执行该sql,这就是我们说的一级缓存失效(也就是没有使用同一个SqlSession对象),而如果开启了Spring事务,那么该Spring事务中的多个sql,在执行时会使用同一个SqlSession对象,从而一级缓存生效。
Spring整合Mybatis后一级缓存失效并不是问题,是正常的实现,因为一个方法如果没有开启Spring事务,那么在执行sql时候,那就是每个sql单独一个事务来执行,也就是单独一个SqlSession对象来执行该sql,如果开启了Spring事务,那就是多个sql属于同一个事务,那自然就应该用一个SqlSession来执行这多个sql。所以,在没有开启Spring事务的时候,SqlSession的一级缓存并不是失效了,而是存在的生命周期太短了(执行完一个sql后就被销毁了,下一个sql执行时又是一个新的SqlSession了)。
总结
今天我们深入解析了 Spring 和 MyBatis 整合的核心组件及其底层实现原理。希望大家通过这次课程能够对 Spring 和 MyBatis 有更深入的理解,并能在实际项目中灵活运用。
👇关注我,下期了解👇
Spring AOP底层源码解析
回复 222,获取Java面试题合集
关于我
一枚爱折腾的Java程序猿,专注Spring干货。把路上的问题记录下来,帮助那些和我一样的人。
好奇心强,喜欢并深入研究古天文。
崇尚 个人系统创建,做一些时间越长越有价值的事情。思考 把时间留下来 又 每刻都是新的。
相关文章:
Spring 整合 MyBatis 底层源码解析
大家好,我是柳岸花开。今天我们要讲的是 Spring 整合 MyBatis 的底层源码解析。希望大家能更深入理解 Spring 和 MyBatis 的整合原理,并应用到实际项目中。 由很多框架都需要和Spring进行整合,而整合的核心思想就是把其他框架所产生的对象放到…...
LeetCode 189.轮转数组
1.这个题我用的方法比较巧妙,大家如果觉得好的话,就给个免费的赞吧^ _ ^,谢谢了。 void reverse(int* nums,int left,int right) {while(left < right){int a nums[left];nums[left] nums[right];nums[right] a;left;right--;} } void rotate(int…...
JDK17 你的下一个白月光
JDK版本升级的非常快,现在已经到JDK20了。JDK版本虽多,但应用最广泛的还得是JDK8,正所谓“他发任他发,我用Java8”。 但实际情况却不是这样,越来越多的java工程师拥抱 JDK17,于是了解了一下 JDK17新语法&a…...
springboot优雅shutdown时如何保障异步线程的安全
我前面写了一篇springboot优雅shutdown的文章,看起来一切很美好。 https://blog.csdn.net/chenshm/article/details/139640775 那是因为没有进行多线程测试。如果一个请求中包括阻塞线程(主线程)和非阻塞线程(异步线程)…...
C++格式化库fmt使用方法
1. 格式化库fmt简介 fmt github地址 api说明 格式化参数说明 内容的格式化,体现在代码中主要表现为字符串、基本类型、自定义类型的拼接。例如说打印日志、拼接变量等。C中我们会经常使用类似printf,snprintf(C风格使用不方便),std::string.append(繁琐), std::io…...
HTML 颜色名:网页设计的调色板
HTML 颜色名:网页设计的调色板 在网页设计和开发中,颜色是一个关键元素,它不仅影响视觉效果,还能传达情感和品牌信息。HTML 颜色名是用于在 HTML 和 CSS 代码中指定颜色的预定义名称。这些颜色名易于记忆,方便设计师和开发者快速选择和应用颜色。本文将详细介绍 HTML 颜色…...
12306 火车票价格解析 (PHP 解析)
1. 从接口拿数据 日期 出发站 终点站 都填上 xxx/otn/leftTicketPrice/queryAllPublicPrice?leftTicketDTO.train_date2024-06-15&leftTicketDTO.from_stationBJP&leftTicketDTO.to_stationSJP&purpose_codesADULT 返回的数据是这样的 {"validateMess…...
了解统计学中不同类型的分布
目录 一、说明 二、均匀分布: 三、机器学习和数据科学中的均匀分布示例: 3.1 对数正态分布: 3.2 机器学习和数据科学中的对数正态分布示例: 四、 帕累托分布 4.1 什么是幂律? 4.2 机器学习和数据科学中的帕累托分布示例…...
k8s-CCE创建工作负载变量引用
CCE创建工作负载变量引用 背景,看到cce创建负载时会生成变量,如下。在skywaking-agent的使用,想要调用cce负载变量生成service_name。 -Dskywalking.agent.authentication里含有敏感信息需要写到配置项。简单粗糙的都写到配置项好像不合适。…...
后端主流框架--Spring02
前言:上篇关于Spring的文章介绍了一些Spring的基本知识,此篇文章主要分享一下如何配置Spring环境,如何注入等。 Spring项目构建 导入Spring相关JAR包 <dependency><groupId>org.springframework</groupId><artifactId>spring…...
[数据集][目标检测]减速带检测数据集VOC+YOLO格式5400张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):5400 标注数量(xml文件个数):5400 标注数量(txt文件个数):5400 标注…...
分析Linux操作指令及使用场景与频率分析 持续更新
本篇主要针对在日常工作与学习中使用较多的linux指令的使用方法以及使用频次进行分析与讲解,旨在能够更好的掌握这些必备的技能。 linux指令非常的多,如果要记住所有的指令使用方法是非常困难的且要花费很长的时间,很多人习惯离开使用去通篇…...
Redis 字符串(String)
Redis 字符串(String) 介绍 Redis是一种开源的、高性能的键值数据库,它支持多种类型的数据结构,其中字符串(String)是Redis中最基本的数据类型之一。字符串类型可以存储任何形式的字符串,包括文本、序列化的对象或二进制数据。在Redis中,字符串类型的最大容量为512MB。 …...
第一篇:容器化的未来:从Docker的革命到云原生架构
容器化的未来:从Docker的革命到云原生架构 1. 引言 在当今快速演进的技术领域,容器化技术已经成为云计算和微服务架构的重要组成部分。该技术以其高效的资源利用率、快速的部署能力和卓越的隔离性能,彻底改变了软件开发和部署的方式。容器化…...
【2024最新华为OD-C/D卷试题汇总】[支持在线评测] URL拼接(100分) - 三语言AC题解(Python/Java/Cpp)
🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 URL拼接(100分) 🌍 评测功能需要订阅专栏后私信联系清隆解…...
反射,枚举以及lambda表达式
【本节目标】 1. 掌握反射 2. 掌握枚举 3. 掌握lambda表达式使用 反射 1 定义 Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调…...
DNS域名解析----分离解析、多域名解析、父域与子域
1 理论部分 1.1 分离解析 DNS的分离解析,是指根据不同的客户端提供不同的域名解析记录。来自不同地址的客户机请求解析同一域名时,为其提供不同的解析结果。也就是内外网客户请求访问相同的域名时,能解析出不同的IP地址,实现负载…...
Spring底层架构核心概念解析
BeanDefinition BeanDefinition表示Bean定义,BeanDefinition中存在很多属性用来描述一个Bean的特点.比如: beanClass:表示Bean类型scope:表示Bean作用域,单例/原型等lazyInit:表示Bean是否懒加载initMethodName:表示Bean初始化时要执行的方法destoryMethodName:表示Bean销毁时…...
C++ 44 之 指针运算符的重载
#include <iostream> #include <string> using namespace std;class Students04{ public:int m_age;Students04(int age){this->m_age age;}void showAge(){cout << "年龄是: " << this->m_age << endl;}~Students0…...
onlyoffice在线预览加载优化
背景: 使用容器部署onlyoffice到linux服务器,使用内网访问速度还可以接受,但是如果放到外网路径访问起来,速度就会很慢,甚至加载失败; 优化方案: 预览的过程排除网络因素,可以发现打…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
