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底层源码执行流程

  1. 通过@MapperScan导入了MapperScannerRegistrar类
  2. MapperScannerRegistrar类实现了ImportBeanDefinitionRegistrar接口,所以Spring在启动时会调用MapperScannerRegistrar类中的registerBeanDefinitions方法
  3. 在registerBeanDefinitions方法中注册一个MapperScannerConfigurer类型的BeanDefinition
  4. 而MapperScannerConfigurer实现了BeanDefinitionRegistryPostProcessor接口,所以Spring在启动过程中时会调用它的postProcessBeanDefinitionRegistry()方法
  5. 在postProcessBeanDefinitionRegistry方法中会生成一个ClassPathMapperScanner对象,然后进行扫描
  6. 设置ClassPathMapperScanner对象可以扫描到接口,因为在Spring中是不会扫描接口的
  7. 同时因为ClassPathMapperScanner中重写了isCandidateComponent方法,导致isCandidateComponent只会认为接口是备选者Component
  8. 通过利用Spring的扫描后,会把接口扫描出来并且得到对应的BeanDefinition
  9. 接下来把扫描得到的BeanDefinition进行修改,把BeanClass修改为MapperFactoryBean,把AutowireMode修改为byType
  10. 扫描完成后,Spring就会基于BeanDefinition去创建Bean了,相当于每个Mapper对应一个FactoryBean
  11. 在MapperFactoryBean中的getObject方法中,调用了getSqlSession()去得到一个sqlSession对象,然后根据对应的Mapper接口生成一个Mapper接口代理对象,这个代理对象就成为Spring容器中的Bean
  12. sqlSession对象是Mybatis中的,一个sqlSession对象需要SqlSessionFactory来产生
  13. MapperFactoryBean的AutowireMode为byType,所以Spring会自动调用set方法,有两个set方法,一个setSqlSessionFactory,一个setSqlSessionTemplate,而这两个方法执行的前提是根据方法参数类型能找到对应的bean,所以Spring容器中要存在SqlSessionFactory类型的bean或者SqlSessionTemplate类型的bean。
  14. 如果你定义的是一个SqlSessionFactory类型的bean,那么最终也会被包装为一个SqlSessionTemplate对象,并且赋值给sqlSession属性
  15. 而在SqlSessionTemplate类中就存在一个getMapper方法,这个方法中就产生一个Mapper接口代理对象
  16. 到时候,当执行该代理对象的某个方法时,就会进入到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底层源码解析

alt

回复 222,获取Java面试题合集

关于我

一枚爱折腾的Java程序猿,专注Spring干货。把路上的问题记录下来,帮助那些和我一样的人。

好奇心强,喜欢并深入研究古天文。

崇尚 个人系统创建,做一些时间越长越有价值的事情。思考 把时间留下来 又 每刻都是新的。

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

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

相关文章

Lua Table(表)

Lua Table(表) Lua 是一种轻量级的编程语言,广泛用于游戏开发、脚本编写和其他应用程序。在 Lua 中,table(表)是一种非常灵活的数据结构,类似于其他语言中的数组、字典或哈希表。Table 可以用来存储各种类型的值,包括数字、字符串、函数,甚至是其他 table。本文将详细…

IDEA创建lib目录,导入jar

IDEA创建lib目录,导入jar lib第一种创建方法: 当发现项目没有lib目录时,File>>>Project Structure 打开Artifacts目录 lib第二种创建方法: 按需选择需要的jar包或者全选即可 lib第三种创建方法:

大疆Pocket2手持记录仪格式化恢复方法

大疆Pocket系列是手持类产品,此类产品处理过不少,今天来看一个Pocket2误格式化之后的恢复方法。 故障存储:256G存储卡 /文件系统:exFAT 故障现象: 客户描述其经常对存储进行格式化,一般重新拍就会格式化一次,需要恢…

一次基于 rebase 的 PR 提交

目录标题 基于 rebase 的 PR 提交git 命令idea 操作 基于 rebase 的 PR 提交 git 命令 1・git fetch 2・git checkout -b dev2 origin/dev2 新拉分支dev23・date >> 1.txt && git add . && g…

深入浅出談 隐马尔可夫的概念(1/ 2)

文章目录 一、说明二、Markov Chain三、Introduction四、State Sequence五、Comment六、介绍隐藏式马可夫法则。七、隐藏马尔可夫Introduction八、结论 一、说明 在许多机器学习的章节中,常常遇见 HMM ,往往看到它的数学式子后,就当没看到似…

springboot事务操作

事务操作 事务处理就是将一个方法中的全部操作当初一个整体,如果其中一个地方报出异常,我们就需要回滚回之前的操作,防止数据混乱,数据缺失 1、Transactional springboot为我们提供了Transactional注解,该注解可以用于…

2-5 基于matlab的信号的希尔伯特-黄变换

基于matlab的信号的希尔伯特-黄变换,IMF分解,对IMF进行Hilbert处理,绘制二维/三维时-频图,时间-能量图(瞬时能量谱) ,频率-能量图(希尔伯特谱)。程序已调通,可直接运行。 2-5 希尔伯…

Bytebase 2.19.0 - 支持 DynamoDB

Bytebase 2.19.0 支持 DynamoDB 支持独立的 SQL 审核工单。 支持为工单事件配置 Slack 私信通知。 file 支持 PostgreSQL 的 DML 变更事前备份。 为 SQL Server 添加 SQL 审核规则:禁止冗余索引。 重大变更 创建多数据库工单时,不同数据库会共享同…

python之面向对象详解(一)

一.类与对象 1.1类和对象的创建 类提供了创建对象的蓝图。对象是类的实例,拥有类中定义的属性和方法。self 参数是对类实例自身的引用,用于访问类的属性和方法。 案例: 下面举一个“长方形”类的例子,包含长,宽属性…

前端进阶-js查漏补缺

1、部分语法基础 1.1、let、const 特性:// 1、暂时行死区 // 比如有这一个例子 let aa "111" function test(){console.log(aa)let aa "22" } // 会报错引用错误,就是因为在函数test作用域内存在暂时性死区,如果把aa…

python pandas处理股票量化数据:笔记2

有一个同学用我的推荐链接注册了tushare社区帐号https://tushare.pro/register?reg671815,现在有了170分积分。目前使用数据的频率受限制。不过可以在调试期间通过python控制台获取数据,将数据保存在本地以后使用不用高频率访问tushare数据接口&#xf…

Scala的字符串插值

Scala的字符串插值 期待您的关注 ☀Scala学习笔记 目录 Scala的字符串插值 1. s插值器: 2. f插值器: 3. raw插值器: 在Scala中,字符串插值是一种方便的方式,可以在字符串中插入变量或表达式的值。Scala支持三种类型…

Mybatis用Map接收返回值可能出现的问题

先看一个示例 明明定义了Map<String,String> 实际内部存放的是Integer resultType是Map 也就是说Mybatis是通过反射将类型放进去的 躲过了编辑器检查 但是这样取值时候就会报类型转换错误 解决方式 resultMap 另外一种方式 用Number Integer和Double的父类 Ma…

大学生计算机基础题(二)

嗨&#xff0c;大家好&#xff0c;我是异星球的小怪同志 一个想法有点乱七八糟的小怪 如果觉得对你有帮助&#xff0c;请支持一波。 希望未来可以一起学习交流。 一、单选题&#xff08;20小题&#xff0c;共30分&#xff09; 1、已知a2,b3,print((ab)%b)的输出结果为&…

Excel/WPS《超级处理器》功能介绍与安装下载

超级处理器是基于Excel或WPS开发的一款插件&#xff0c;拥有近300个功能&#xff0c;非常简单高效的处理表格数据&#xff0c;安装即可使用。 点击此处&#xff1a;超i处理器安装下载 Excel菜单&#xff0c;显示如下图所示&#xff1a; WPS菜单显示&#xff0c;如下图所示&am…

15.混合专家模型(MoEs)技术揭秘

混合专家模型&#xff08;MoEs&#xff09;技术揭秘 混合专家模型&#xff08;Mixture-of-Experts, MoEs&#xff09;技术发展简史 Mixtral 8x7B &#xff1a;质效并举的稀疏混合专家模型 Mixtral 8x7B &#xff1a;质效并举的稀疏混合专家模型 MoEs 技术发展简史 MoEs 开山…

matplotlib twinx多y轴但单个图例

matplotlib 用 twinx 画多 y 轴参考 [1]。现想在画图例时&#xff0c;多个 y 轴的图例画在一起&#xff0c;写法参考 [2]。本文展示一个简例&#xff0c;效果&#xff1a; Code 要手动指定颜色&#xff0c;否则原 y 轴的用色和新 y 轴会重合。 import matplotlib.pyplot as…

永磁同步直线电机(PMLSM)控制与仿真2-永磁同步直线电机数学模型搭建

文章目录 1、公式总结2、电压方程模型3、运动方程4、推力方程5、转化关系 写在前面&#xff1a;原本为一篇文章写完了永磁同步直线电机数学模型介绍&#xff0c;永磁同步直线电机数学模型搭建&#xff0c;以及永磁同步直线电机三环参数整定及三环仿真模型搭建&#xff0c;但因为…

Dockerfile小技巧(通过变量指定程序配置文件内容)

思路&#xff1a;Dockerfile中定义变量&#xff0c;程序配置文件中使用占位符暂时代替变量内容&#xff0c;最后使用变量值替换占位符实现&#xff0c;这样就可以实现通过定义变量来定义程序启动时的一些参数了。 1、我以构建Nginx镜像为例&#xff0c;作为演示&#xff0c;Do…

TCP及UDP协议

tcp是点到点的&#xff0c;只有一条路径&#xff0c;到达顺序和发送顺序是相同的 回复的确认号是序发送端的序列号加上data的长度 1910 发送端的序列号也是那么算的 ack和下一个seq一样 那就没问题 三次握手四次挥手&#xff1a; 为啥是三次呢&#xff1f; 假如一次&#xf…