通俗易懂理清mybatis中SqlSessionSql、SqlSessionTemplate、SessionFactory和SqlSessionFactoryBean之间的关系
我潇洒的灰大狼又回来啦。今天送大家的一句话是:
保持耐心,永远年轻,永远热泪盈眶。
前言
先容我哭一会儿,呜呜呜~昨晚写了一半的文章,还没保存就盖上盖子准备回家,拔下电源准备把电脑塞进书包带回家完成时,懒惰阻止了我,最终还是没带回家,于是,遭报应了,今天早上来,电脑直接就是没电关机了,开机后写的文章再也找不回来了...(不争气的mac真是对不起我前面特地写了一篇文章来夸赞mac真香啊...)
Thread.sleep(5000);//crying...
回归正题,开始含泪创作了。
很多初学者在学习mabatis或者看公司的mybatis项目时,总是搞不清楚SqlSessionSql、SqlSessionTemplate、SessionFactory和SqlSessionFactoryBean这几者之间的关系,尤其是我们在看别人的代码时,不同的项目都是不同的人完成的,风格迥异,有人用spring配置的形式,有人用springboot硬编码的形式,更有复杂点的项目,使用了读写分离等等,很容易让人懵圈。这篇文章的目的就是用通俗易懂的方式给大家理清这几者之间的关系。如若您发现文章某些部分难以理解,或者有错误,还望不惜笔墨,吾当虚心接受,感激涕零。如若您觉得有帮助,点个赞支持下,感谢感谢~
来,打起精神来。
正文
SqlSession和SqlSessionTemplate
首先给大家带来的是SqlSession和SqlSessionTemplate之间的关系,先看图,再看描述。

SqlSession实现了Closeable接口,代表SqlSession是可以关闭的,那也就是说SqlSession代表一种可关闭的连接。正如他的名字,session表示的是一个会话,用来维护无状态请求之间的状态信息,放在数据库这里,SqlSession表示的是数据库客户端和数据库服务端之间的一种会话,并维护了两者之间的状态信息。

我们看到,SqlSession是一个接口,里面有我们熟悉的操作数据库执行sql语句的select、insert、update等方法,是不是很熟悉。

SqlSession有三个实现类,当然,你也可以自己实现。DefaultSqlSession是它的默认实现类,当然,还有我们熟悉的SqlSessionTemplate实现类。小伙伴们是不是已经打开代码开始看了,如果还没有,我建议你打开源码,跟着我的思路往下走。


聪明的你是不是早就已经发现了,DefaultSqlSession和SqlSessionTemplate差别很大,但是咱们这次讨论的重点是SqlSessionTemplate,就不展开讲述他们之间的区别了,其实如果你能认真看到最后,你就自然就清楚区别了。

值得一提的是,SqlSessionTemplate除了实现了Sqlsession接口之外,还实现了DisposableBean接口,这就意味着,SqlSessionTemplate的实例被Bean工厂发现后,会把他们纳入整个spring bean生命周期的管理过程之中,当BeanFactory尝试销毁时,Beans的管理者会以回调的方式调用SqlSessionTemplate的destroy()方法。

默认实现是空方法,具体你可以自己重写。
总结一下,SqlSessionTemplate是SqlSession的实现类,如其名,是sqlSession模板,有了SqlSessionTemplate,我们就能用来执行Dao层的Sql语句。说了这么多,其实关键就一点,SqlSessionTmplate是SqlSession的实现类,而这个实现类中有一个关键的类就是SqlSessionFactory。
SqlSessionFactory和SqlSessionFactoryBean

SqlSessionFactory也是一个接口,是SqlSession工厂,他的能力就是打开一个SqlSession会话,而且重载了许多不同的参数,你可以改变这些参数自定义会话过程中的一些默认行为。例如:可以设置自动提交事务或是关闭自动提交;可以设置获取数据库连接的线程的类型(重用,每次新产生等等);也可以获取整个Mybatis的配置信息的Configuration对象实例等等。

SqlSessionFactory默认也有两个实现类,当然你也可以自定义实现类。默认实现是DefaultSqlSessionFactory。
总而言之,SqlSessionFactory就是生产SqlSession对象的工厂。那也就是说整个Mybatis中,如果只有一个数据库Server要连接,那么只需要一个工厂就够了(只有一个SqlSessionFactory的实例对象),而SqlSession可以自由的被关闭,也就代表SqlSession是需要反复被创建的。上面说到SqlSession是关联到具体数据库连接的,但是如果每次创建和销毁都直接操作物理连接的话,那么这个资源浪费很高,效率很低。请看DefaultSqlSessionFactory的方法:

上图是基于数据库连接池实现的,也就是说一次连接用完关闭SqlSession实例时,只是把数据库连接对象放回到对象池中,并没有直接销毁,使用池技术,大大提高了物力资源利用率,缩短连接时间、减少了资源利用等。
讲到这里,细心的小伙伴们可能有个疑问,SqlSessionFactory是怎么创建SqlSession的,或者更具体点,是怎么创建SqlSessionTemplate的,这就不得不说动态代理了。这部分是在SqlSessionTemplate中实现的,具体细节我下期再从源码角度给大家分享。
所剩不多了,再坚持坚持,坚持看完。
接下来要说的是SqlSessionFactoryBean,老规律,类图如下:

实现了ApplicationListener接口,代表SqlSessionFactoryBean有能力监控 Application发出的一些事件通知。
实现了FactoryBean接口,代表SqlSessionFactoryBean的实例不再是一个普通的bean对象,而是可以产生自己Bean的一个工厂,并且产生的Bean会被纳入spring的生命周期,这里产生的Bean指的就是SqlSessionFactory。
实现了InitializingBean接口,代表SqlSessionFactoryBean中的afterPropertiesSet()方法会在Bean初始化属性完成后立即被调用。
如其名,SqlSessionFactoryBean是生产SqlSessionFactory的工厂bean。
综上所述
SqlSessionFactoryBean是生产SqlSessionFactory的一种工厂bean。
SqlSessionFactory是打开SqlSession会话的工厂,是一个接口,可以根据需求自己实现,它的默认实现类DefaultSqlSessionFactory使用了数据库连接池技术。
SqlSession是客户端和数据库服务端之间的会话信息,里面有许多操作数据库的方法。
SqlSessionTemplate是SqlSession的一个具体实现。
写在最后
写到这里,不知道小伙伴们是否已经搞清楚他们之间的关系了呢。上面讲的其实比较浅显,主要是从结构上给大家梳理了下他们之间的关系,以及它们每一个的作用,但是这还远远不够,就像上面提到的,SqlSessionTemplate和SqlSession、SqlSessionFactory之间的纠缠到底是怎么样的?DataSource、Connection是怎么发挥作用的?以及我们的代码中是如何产生Sql语句并发送给数据库Server的?
爱学习的你们,是不是迫不及待想要一探究竟了,关注我,且听我灰大狼下期通过源码的方式给你们一一拆解。
有帮助?点个赞再走呗~感谢各位老铁的支持~
相遇即是缘分,如果这篇文章对您有帮助,请您动动手指点个赞支持一下,这对我非常重要,感谢您的支持!
通俗易懂理清mybatis中SqlSessionSql、SqlSessionTemplate、SessionFactory和SqlSessionFactoryBean之间的关系的更多相关文章
- storm中worker、executor、task之间的关系
这里做一些补充: worker是一个进程,由supervisor启动,并只负责处理一个topology,所以不会同时处理多个topology. executor是一个线程,由worker启动,是运行t ...
- Android进阶笔记08:Android 中Activity、Window和View之间的关系
1. Android 中Activity.Window和View之间的关系(比喻): Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图) LayoutI ...
- C++中 0 与 NULL 与 nullptr之间的关系,nullptr_t 的实现
C++中 0 与 NULL 与 nullptr之间的关系,nullptr_t 的实现 来源 http://blog.csdn.net/Virtual_Func/article/details/4975 ...
- FFMPEG中最要害的结构体之间的关系
FFMPEG中最关键的结构体之间的关系 http://www.myexception.cn/program/1404591.html FFMPEG中结构体很多.最关键的结构体可以分成以下几类: a) ...
- python中,ascii,unicode,utf8,gbk之间的关系梳理
在计算机中,经常遇到编码问题,本节主要梳理下ascii,unicode,utf8,gbk 这几种编码之间的关系. ASCII 计算机中,所有数据都以0和1来表示.在一开始的时候,要表示的内容比较少,人 ...
- js中prototype,__proto__,constructor之间的关系
首先,我们需要了解三点: 1. 只要创建一个任意新函数,就会根据一个prototype属性,该属性指向函数的原型对象: 2. 每一个原型对象都会自动获得一个constructor属性,该属性只想pro ...
- Zstack中任务,事件,消息之间的关系
Zstack是Zigbee协议的具体实现,在实现的过程中为了能够更好的对各个模块和功能进行管理,所以加入了OSAL(Operating System Abstraction Layer 操作系统抽象层 ...
- Java中接口与接口和类之间的关系
接口和接口之间的关系 继承关系 可以多继承,并且可以多层继承 注意: 1.如果多个父接口中有同名的抽象方法,那么子接口只需要实现一次即可 2.如果多个父接口中有同名的默认方法,那么子接口必须重写默认方 ...
- Android中的APK,TASK,PROCESS,USERID之间的关系
开发Android已经有一段时间了,今天接触到底层的东西,所以对于进程,用户的id以及Android中的Task,Apk之间的关系,要做一个研究,下面就是研究结果: apk一般占一个dalvik,一个 ...
随机推荐
- iPython的安装过程
http://blog.csdn.net/u012587561/article/details/50900781 python2.7.10 amd64 win10 x64 1. 安装setuptool ...
- win10 + 独显 + Anaconda3 + tensorflow_gpu1.13 安装教程(跑bert模型)
这里面有很多坑,最大的坑是发现各方面都装好了结果报错 Loaded runtime CuDNN library: 7.3.1 but source was compiled with: 7.4.1, ...
- HTML5--语法
一.标记方法 1.内容类型(ContentType)还是.text/html 2.声明:<!DOCTYPE html SYSTEM “about:legacy-compat”> 3.字符编 ...
- Unity5.6.4f1 配置WebGL教程
Unity 5.6.4f1 发布WebGL的配置教程 步骤一:先查看自带的Unity是否yi配置好WebGL的项,若无,则可遵循以下教程来设置 步骤二:下图是我已经设置好的,未设置好的状态是,有个Op ...
- 《Netty权威指南》(一)简单的时间服务器P69
由于该书是基于Netty5编写的样例代码,而Netty5已经被官方废弃. 目前基于推荐版的4.1.12.Final在学习过程中,可能会出现个别接口不一致的情况.所以记录可在4.1.12下编译通过的代码 ...
- Codeforces Round #561 (Div. 2) E. The LCMs Must be Large(数学)
传送门 题意: 有 n 个商店,第 i 个商店出售正整数 ai: Dora 买了 m 天的东西,第 i 天去了 si 个不同的个商店购买了 si 个数: Dora 的对手 Swiper 在第 i 天去 ...
- Vue 中的过滤器的使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- .map() .filter() .reduce() .includes() .some() .every()的用法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- win10 uwp 解决 SerialDevice.FromIdAsync 返回空
调用 SerialDevice.FromIdAsync 可能返回空,因为没有设置 package.appmanifest 可以使用端口 打开 package.appmanifest 文件添加下面代码 ...
- Vue中的computed和watch
看了网上很多资料,对vue的computed讲解自己看的都不是很清晰,今天忙里抽闲,和同事们又闲聊起来,对computed这个属性才有了一个稍微比较清晰的认识,下面的文章有一部分是转自: https: ...