通俗易懂理清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,一个 ...
随机推荐
- day6_python序列化之 json & pickle & shelve 模块
一.json & pickle & shelve 模块 json,用于字符串 和 python数据类型间进行转换pickle,用于python特有的类型 和 python的数据类型间进 ...
- oracle 优化GROUP BY
提高GROUP BY 语句的效率, 可以通过将不需要的记录在GROUP BY 之前过滤掉.下面两个查询返回相同结果但第二个明显就快了许多. 低效: SELECT JOB , AVG(SAL) FROM ...
- 自然语言处理课程(二):Jieba分词的原理及实例操作
上节课,我们学习了自然语言处理课程(一):自然语言处理在网文改编市场的应用,了解了相关的基础理论.接下来,我们将要了解一些具体的.可操作的技术方法. 作为小说爱好者的你,是否有设想过通过一些计算机工具 ...
- hdu 1255 覆盖的面积 (Bruceforce)
Problem - 1255 暴力统计覆盖超过一次的区域.1y. 代码如下: #include <cstdio> #include <cstring> #include < ...
- springboot 项目打包可运行jar文件
eclipse 运行run as maven bulid ,填入package ,运行打包 java -jar xxx.jar
- python3在pycharm中为什么导入random模块不能用? TypeError: 'module' object is not callable
新手学python求大神指导,也用sys导入了random.py的路径,仍然不行. 刚刚排错貌似找到了问题的原因...那是因为我在pycharm中新建的python文件名就是random,所以当前目录 ...
- H5 FileReader读取文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- linux模块参数
驱动需要知道的几个参数因不同的系统而不同. 从使用的设备号( 如我们在下一章见到的 ) 到驱动应当任何操作的几个方面. 例如, SCSI 适配器的驱动常常有选项控制标记命令队列 的使用, IDE 驱动 ...
- H3C 路由优先级
- 开源项目使用 appveyor 自动构建
我写了几个开源项目,我想要有小伙伴提交的时候自动运行单元测试,自动运行编译,这样可以保证小伙伴提交清真的代码 本文将会告诉大家如何接入 appveyor 自动构建方案,在 Github 上给自己的开源 ...