全网最通俗易懂理清mybatis中SqlSession、SqlSessionTemplate、SessionFactory和SqlSessionFactoryBean之间的关系

摘自:https://www.cnblogs.com/xiaoming0601/p/12166160.html

我潇洒的灰大狼又回来啦。今天送大家的一句话是:

保持耐心,永远年轻,永远热泪盈眶。

前言

先容我哭一会儿,呜呜呜~昨晚写了一半的文章,还没保存就盖上盖子准备回家,拔下电源准备把电脑塞进书包带回家完成时,懒惰阻止了我,最终还是没带回家,于是,遭报应了,今天早上来,电脑直接就是没电关机了,开机后写的文章再也找不回来了...(不争气的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后端SqlSession

原文地址:https://www.cnblogs.com/xichji/p/12342569.html

时间: 2024-10-13 14:10:37

全网最通俗易懂理清mybatis中SqlSession、SqlSessionTemplate、SessionFactory和SqlSessionFactoryBean之间的关系的相关文章

Android进阶笔记08:Android 中Activity、Window和View之间的关系

1. Android 中Activity.Window和View之间的关系(比喻): Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图) LayoutInflater像剪刀,Xml配置像窗花图纸.  2. 详解:       Activity是Android应用程序的载体,允许用户在其上创建一个用户界面,并提供用户处理事件的API,如onKeyEvent, onTouchEvent等. 并维护应用程序的生命周期.Activity本身是个庞大的载体,

Mybatis 中sqlsession源码解析

一.sqlsession获取过程 1.基础配置 在mybatis框架下进行的数据库操作都需要首先获取sqlsession,在mybatis与spring集成后获取sqlsession需要用到sqlsessionTemplate这个类. 首先在spring对sqlsessionTemplate进行配置,使用到的是 org.mybatis.spring.SqlSessionTemplate 这个类. <!-- SqlSession实例 --> <bean id="sessionTe

storm中worker、executor、task之间的关系

理清一下worker.executor.task.supervisor.nimbus.zk这几个之间的关系 先来看一张图 (图片来自:http://www.cnblogs.com/foreach-break/p/storm_worker_executor_spout_bolt_simbus_supervisor_mk-assignments.html) 首先从微观上来看:worker即进程,一个worker就是一个进程,进程里面包含一个或多个线程,一个线程就是一个executor,一个线程会处理

python中,ascii,unicode,utf8,gbk之间的关系梳理

在计算机中,经常遇到编码问题,本节主要梳理下ascii,unicode,utf8,gbk 这几种编码之间的关系. ASCII 计算机中,所有数据都以0和1来表示.在一开始的时候,要表示的内容比较少,人们使用了ascii编码的方式来编码. ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言,其最多只能用 8 位来表示(一个字节),即:2**8 -

js中prototype,__proto__,constructor之间的关系

首先,我们需要了解三点: 1. 只要创建一个任意新函数,就会根据一个prototype属性,该属性指向函数的原型对象: 2. 每一个原型对象都会自动获得一个constructor属性,该属性只想prototype所在函数的指针: 3. 当调用构造函数创建实例时,该实例内部将包含一个指向构造函数原型对象的指针,在大部分浏览器中用__proto__标识: 从上面这三点我们可以了解到: 正常情况下:prototype属性 -> 原型对象 原型对象的constructor属性 -> 构造函数(即拥有p

Zstack中任务,事件,消息之间的关系

Zstack是Zigbee协议的具体实现,在实现的过程中为了能够更好的对各个模块和功能进行管理,所以加入了OSAL(Operating System Abstraction Layer 操作系统抽象层)(以上为个人见解). 在OSAL中,提出了任务,事件,消息三个概念.它们之间的关系如下: 任务是处理事件的一个功能集合,一般由一个事件处理函数实现(ProcessEvents) 事件是当前系统中被触发的动作,例如有按键按下,接收到其他节点发送过来的消息等等 消息则是事件编号和其对应事件内容的集合,

Java中接口与接口和类之间的关系

接口和接口之间的关系 继承关系 可以多继承,并且可以多层继承 注意: 1.如果多个父接口中有同名的抽象方法,那么子接口只需要实现一次即可 2.如果多个父接口中有同名的默认方法,那么子接口必须重写默认方法,必须要加default关键字3.如果多个父接口中有同名的静态方法,那么无须理会,因为静态方法只能供接口使用 4.如果多个父接口中有同名的私有方法,那么无须理会,因为私有方法只能本接口使用 接口和类之间的关系 实现关系 单实现: 一个类只实现一个接口 多实现: 一个类可以同时实现多个接口 格式:

使用ThreadLocal管理Mybatis中SqlSession对象

转自http://blog.csdn.net/qq_29227939/article/details/52029065 public class MybatisUtil { private static SqlSessionFactory factory; // 解决资源争抢问题. private static ThreadLocal<SqlSession> localSessions = new ThreadLocal<SqlSession>(); static { Reader

SSM-MyBatis-10:Mybatis中SqlSession的getMapper()和简单的工具类MyBatisUtils

------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- getMapper的作用,获取到接口,直接通过点的方式调用方法,以免直接手打的方式写错方法名,(强类型的方式) 例子: IBookDAO mapper = session.getMapper(IBookDAO.class); List<Book> list = mapper.findAllBook(); 那个工具类,主要是获取SqlSession对象,写法 package cn.dawn.util; im