mybatis是如何集成到spring的?

news2025/1/22 12:38:06

文章目录

  • 1 前言
    • 1.1 集成spring前使用mybatis的方式
    • 1.2 集成mybatis到spring的关键步骤
  • 2 SqlSessionFactoryBean对象分析
    • 2.1 buildSqlSessionFactory做了什么事情?
    • 2.2 为什么是SqlSessionFactoryBean却可以使用SqlSessionFactory?
  • 3 验证demo
  • 4 举一反三
    • 4.1 插件的配置是在SqlSessionFactoryBean的定义里面还是configuration的xml结点下面?
    • 4.2 mybatis的事务管理和spring的事务管理什么关系?
  • 5 总结

1 前言

1.1 集成spring前使用mybatis的方式

mybatis单独使用时,一般的写法如下所示:

// mybatis初始化
String resource = "mybatis-config.xml";  
InputStream inputStream = Resources.getResourceAsStream(resource);  
// 读取配置文件,创建SqlSessionFactory 
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

// 打开SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();  

// 执行SQL语句
List list = sqlSession.selectList("com.gameloft9.demo.dataaccess.dao.system.UserMapper.getByLoginName");

1.2 集成mybatis到spring的关键步骤

将mybatis集成到spring之后,就可以被spring的ioc容器托管,再也不用自己创建SqlSessionFactory 、打开SqlSession等操作。具体的集成方法可以参考之前写的文章:spring集成mybatis进行数据库访问,其中最重要的配置就是定义好SqlSessionFactoryBean,如下所示:

<!--mybatis sqlSeesionFactory配置-->
		<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
			<property name="dataSource" ref="dataSource" />
			<property name="configLocation" value="classpath:mybatis-config.xml" />
			<property name="mapperLocations" value="classpath:mapper/*Mapper.xml" />
			<property name="typeAliasesPackage" value="com.gameloft9.demo.dataaccess.model" />
		</bean>

因此想要了解spring集成mybatis的原理,就应该从SqlSessionFactoryBean入手。

2 SqlSessionFactoryBean对象分析

SqlSessionFactoryBean,顾名思义跟SqlSessionFactory有着莫大的关系,它的类结构如下所示:
在这里插入图片描述
SqlSessionFactoryBean实现了InitializingBean接口,我们知道InitializingBean在Bean的生命周期里面扮演了重要的角色,spring创建bean的流程大概是:
1、创建beanFactory
2、加载beanDefinition
3、通过反射创建bean实例
4、bean的生命周期扩展点调用
其中第4步骤又包含:
5、如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。
6、如果bean实现IntializingBean了,调用它的afterPropertySet方法。
7、如果bean定义了init-method,调用init方法
8、如果有BeanPostProcessors 和bean 关联,这些bean的postProcessAfterInitialization() 方法将被调用。
9、如果bean实现了 DisposableBean,它将调用destroy()方法。
10、如果bean定义了destroy-method,调用destroy方法。
因此在我们xml配置好的dataSource,configLocation等属性设置好后,SqlSessionFactoryBean就在afterPropertySet()方法里面对SqlSessionFactory进行初始化。
在这里插入图片描述

2.1 buildSqlSessionFactory做了什么事情?

buildSqlSessionFactory里面就是具体怎么创建SqlSeesionFactory的,代码流程比较长,我们用一个简单时序图来展示:
在这里插入图片描述
在解析完各种配置后,调用了return this.sqlSessionFactoryBuilder.build(configuration);来创建buildSqlSessionFactory,是不是和之前的方式很类似了?只是一个是入参是resource,一个是我们解析后的配置configuration对象。

2.2 为什么是SqlSessionFactoryBean却可以使用SqlSessionFactory?

我们注册的是SqlSessionFactoryBean这个bean,为什么却说SqlSessionFactory也成为了spring的bean呢?因为我们的SqlSessionFactoryBean还实现了FactoryBean这个接口。

Spring 中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean 即 FactoryBean。FactoryBean跟普通Bean不同,其返回的对象不是指定类的一个实例,而是该FactoryBean的getObject方法所返回的对象。
一般情况下,Spring通过反射机制利用的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。

然后回到maybatis这里,我们通过时序图确实发现创建SqlSessionFactory十分复杂,要解析大量的配置之后才能创建,因此我们实现了FactoryBean接口:
在这里插入图片描述
在getObject里面选择性的进行初始化并返回SqlSessionFactory对象。
至于获取SqlSessionFactorybean实例的时候,是怎么走到FactoryBean的getObject的方法的,可以参考AbstractBeanFactory.getBean方法,这属于spring ioc范畴了,这个需要很长的篇幅才能讲清楚,有机会我会单独写一篇spring怎么创建bean和获取bean的。

3 验证demo

如果你有demo的话,可以单步跟踪。如果没有的话,可以使用作者之前做过的一个基于layui的通用后台系统,简单的安装mysql和客户端之后(本地安装mysql和客户端真的很简单30分钟搞定吧)、稍微改下配置就可以直接运行这个项目(这个项目麻雀虽小,但五脏俱全,如果觉得好用,可以帮忙点个start)。

验证之前,我们先做个猜想:SqlSessionFactory是在afterPropertiesSet里初始化的还是在getObject里判断为空再初始化的?

我们分别在SqlSessionFactoryBean的afterPropertiesSet和getObject打上断点,然后debug项目,如下所示:
在这里插入图片描述
可以看到,在SqlSessionFactoryBean实例创建后,在afterPropertiesSet对SqlSessionFactory进行了初始化和创建。然后在获取它的时候,走的是getObject方法(这时候sqlSessionFactory已经不为空了):
在这里插入图片描述

4 举一反三

4.1 插件的配置是在SqlSessionFactoryBean的定义里面还是configuration的xml结点下面?

demo里的插件我们是写在mybatis-config.xml里面的configuration结点里面的,如下所示:
在这里插入图片描述
这是通用的做法,当然你也可以经常看到有人配置在SqlSessionFactoryBean的定义里面,如下所示:
在这里插入图片描述
那么问题来了,这两个有什么区别吗?
这个比较简单,作者自问自答一下。
这两个都可以作为插件的配置方式,都会起作用,因为在buildSqlSessionFactory过程中,如果发现插件不为空,就会添加到插件集合里面去,如下所示:
在这里插入图片描述
然后再解析xml时,又会将configuration的配置解析一遍,里面也包含插件的解析过程:
在这里插入图片描述
在这里插入图片描述
所以我们只需要在一个地方配置好就行了。然后它们有一个细微的差别,因为configuration是mybatis的配置,所以在configuration中的插件配置,是通过调用setProperties方法将属性传递进来,然后设置到插件的属性中。SqlSessionFactoryBean的插件配置不会调用setProperties方法,直接走的setter注入将属性注入进去。
在这里插入图片描述
这个大家也可以自行验证下。

4.2 mybatis的事务管理和spring的事务管理什么关系?

如果你仔细看了SqlSessionFactoryBean创建SqlSessionFactory的过程,那么肯定会注意到有这么一个调用:

if (this.transactionFactory == null) {
      this.transactionFactory = new SpringManagedTransactionFactory();
    }

因为我们配置的是spring的事务,在mybatis的配置文件里面没有为SqlSessionFactoryBean配置事务,如下所示:
在这里插入图片描述
所以那段代码里面transactionFactory会因为==null,而创建一个SpringManagedTransactionFactory,下面的截图也刚好印证了我们的观点。
在这里插入图片描述
那么问题来了,mybatis的事务和spring的事务是什么关系?它们是怎么配合的?
这个问题回答比较复杂,需要有spring事务的知识,大家可以尝试自己找答案,或者等作者后续的文章来解答。

5 总结

mybatis通过SqlSessionFactoryBean将SqlSessionFactory对象集成到spring中,它实现了InitializingBean接口,在SqlSessionFactoryBean初始化时解析配置并创建DefaultSqlSessionFactory对象。它还实现了FactoryBean,在getObject时返回我们创建好的DefaultSqlSessionFactory,使得DefaultSqlSessionFactory也被spring管理起来。
很多框架集成到spring的方法基本都是靠InitializingBean和FactoryBean这两个接口来实现的,这是一种非常好的设计,值得我们好好学习。

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

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

相关文章

【Python 爬虫之BeautifulSoup】零基础也能轻松掌握的学习路线与参考资料

BeautifulSoup是一种Python库&#xff0c;用于解析HTML和XML文档&#xff0c;并从中提取数据。它提供了Pythonic的解决方案来处理非结构化数据&#xff0c;因此可以轻松地从网页上提取数据。 使用BeautifulSoup编写爬虫&#xff0c;你可以自动化许多任务&#xff0c;比如数据抓…

实验三 Spark SQL基础编程

实验三 Spark SQL基础编程 1.实验目的 1. 掌握 Spark SQL 的基本编程方法&#xff1b; 2. 熟悉 RDD 到 DataFrame 的转化方法&#xff1b; 3. 熟悉利用 Spark SQL 管理来自不同数据源的数据。 2.实验内容 1&#xff0e;Spark SQL 基本操作 将下列 JSON 格式数据复制到 Li…

CF1245D Shichikuji and Power Grid 题解

CF1245D Shichikuji and Power Grid 题解 题目链接字面描述题面翻译样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示 思路点拨代码实现 题目 链接 https://www.luogu.com.cn/problem/CF1245D 字面描述 题面翻译 已知一个平面上有 n n n 个城市&#x…

计网笔记 数据链路层 (1-2) 封装成帧、差错控制、流量控制与可靠传输、停止等待协议、后退N帧协议(GBN)、选择重传协议(SR)

文章目录 前言在这里插入图片描述 零、数据链路层基本概念一、功能0、数据链路层功能概述1、封装成帧和透明传输1.1封装成帧1.2 透明传输1.3组帧方法 2、数据链路层的差错控制2.0差错从何而来2.1位错&#xff08;比特错&#xff0c;1变成0&#xff0c;0变成1&#xff09;2.2帧错…

干货 | ChatGPT使用指南,让你轻松上车AI世界!

Hello&#xff0c;大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐~ 聊天机器人&#xff08;Chatbot&#xff09;是一种人工智能应用&#xff0c;可以模拟人类对话行为&#xff0c;以自然语言进行交互。 在过去的几年里&#xff0c;随着自然语言处理技术和深…

Springboot +Flowable,定时器的简单使用

一.流程定义定时激活 之前介绍流程定义的时候&#xff0c;流程都是定义好之后立马就激活了&#xff0c;其实在流程定义的这个过程中&#xff0c;我们还可以设置一个激活时间&#xff0c;也就是流程定义好之后&#xff0c;并不会立马激活&#xff08;不激活就不能据此流程定义创…

操作系统作业 第37-40章

第四次作业 第37章 本章作业需要使用提供的disk.py程序。该程序可以模拟磁盘的工作。在默认情况下&#xff0c;磁盘调度方法为FIFO。对于时间的计算&#xff0c;假设旋转一度为1个时间单位&#xff0c;旋转完整一圈需要360个时间单位&#xff0c;而一个磁道上默认有12个扇区&…

实验二 RDD基础编程

实验二 RDD基础编程 前提是配置好大数据环节。 hadoop&#xff0c;spark&#xff0c;scala等必须的软件 以及下载pyshark 1.实验目的 1. 掌握 RDD 基本操作&#xff1b; 2. 熟悉使用 RDD 编程解决实际具体问题的方法&#xff1b; 2.实验内容 本人仅提供测试代码&#xff01;…

策划专业技能提升攻略,让你在职场中脱颖而出

作为一个10多年的老策划&#xff0c;刚入行的时候也走过很多弯路&#xff0c;后来加入到一家在国内比较知名的策划公司&#xff08;老板也是当年的十大知名策划人&#xff09;才真正让我实现水平的跃升。 当时公司经常有内训&#xff0c;新人的第一课就是策划人应该如何快速入…

FreeRTOS-事件组详解

✅作者简介&#xff1a;嵌入式入坑者&#xff0c;与大家一起加油&#xff0c;希望文章能够帮助各位&#xff01;&#xff01;&#xff01;&#xff01; &#x1f4c3;个人主页&#xff1a;rivencode的个人主页 &#x1f525;系列专栏&#xff1a;玩转FreeRTOS &#x1f4ac;保持…

深入理解JVM读书笔记与实战_01_Java内存区域与内存溢出异常

文章目录 运行时数据区域问题引入 运行时数据区域 Java虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区。运行时数据区包括了程序计数器、虚拟机栈、本地方法栈、方法区和堆。 程序计数器&#xff1a;程序计数器是线程私有的内存&#xff0c;用来记住…

vue:组件使用v-model实现2个组件间的数据双向绑定

一、需要实现的需求&#xff1a; 子组件输入框的数据发生改变&#xff0c;父组件的数据跟着实时改变&#xff1b; 父组件的数据发生改变&#xff0c;子组件的数据跟着实时改变。 二、实现思路&#xff1a; 1、&#xff08;1&#xff09;在父组件引入子组件。&#xff08;2&…

CAN总线要点总结(CAN2.0A/B)

个人博客原文链接&#xff1a;CAN总线要点总结&#xff08;CAN2.0A/B&#xff09; 前言 工作也有几年了&#xff0c;在项目中也接触过几次CAN总线&#xff0c;但总是止步于会用即可&#xff0c;对于很多细节上的东西有时还是稀里糊涂的状态&#xff0c;这几天正好有点时间&am…

【亲测有效】pycharm不显示软件包

http://pypi.hustunique.com/ https://pypi.mirrors.ustc.edu.cn/ http://pypi.tuna.tsinghua.edu.cn/simple/ http://mirrors.aliyun.com/pypi/simple/ http://pypi.douban.com/simple/2023.5.13 亲测有效

单点登录系统:登录,登出,拦截器

什么是单点登录&#xff1f; 单点登录&#xff08;Single Sign On&#xff09;&#xff0c;简称为 SSO&#xff0c;是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中&#xff0c;用户只需要登录一次就可以访问所有相互信任的应用系统。 假设一个企业…

贪心算法(无规则)

目录 1.easy1.455. 分发饼干2.1005. K 次取反后最大化的数组和3.860. 柠檬水找零 2.medium1.序列问题1.376. 摆动序列2.738. 单调递增的数字 2.贪心解决股票问题1.122. 买卖股票的最佳时机 II 3.两个维度权衡问题1.135. 分发糖果*2.406. 根据身高重建队列(linklist&#xff0c;…

【WOA-LSTM】基于WOA优化 LSTM神经网络预测研究(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Neuron 2.4.0 发布:体验下一代工业物联网连接和管理

近日&#xff0c;EMQ 旗下的工业协议网关软件 Neuron 发布了最新的 2.4.0 版本。 该版本新增了包括 ABB COMLI 在内的四个南向驱动和一个北向应用&#xff0c;同时对现有的插件功能和 UI 进行了优化。 快速体验 Neuron 新版本 新增驱动插件满足不同场景需求 IEC61850 MMS 和 …

springboot项目如何优雅停机

文章目录 前言kill -9 pid的危害如何优雅的停机理论步骤优雅方式1、kill -15 pid 命令停机2、ApplicationContext close停机3、actuator shutdown 停机 前言 相信很多同学都会用Kill -9 PID来杀死进程&#xff0c;如果用在我们微服务项目里面&#xff0c;突然杀死进程会有什么…

计算机组成原理基础练习题第二章

1.下面四种语言中&#xff0c;()更适应网络环境 A、FORTRAN    B、JavaC、C        D、PASCAL 2.下列叙述中正确的是&#xff08;&#xff09; A.终端是计算机硬件的一部分,好比电视中的小屏幕 B. ALU是代数逻辑单元的缩写 C.导航用计算机属于一般用途计算…