Mybatis中SqlSession、SqlSessionTemplate、SqlSessionFactory、SqlSessionFactoryBean之间的关系
摘抄自: https://www.jianshu.com/p/f19a58938959
1. SqlSession和SqlSessionTemplate
SqlSession实现了Closeable接口,代表SqlSession是可以关闭的,那也就是说SqlSession代表一种可关闭的连接,也正如名字所表达的是Session,Session对于开发人员来说并不陌生。例如:浏览器和服务器之间的会话也是Session,Session用来维护无状态请求之间的状态的信息。所以说SqlSession也是一种会话,数据库连接客户端和数据库Server之间的一种会话,并维护了客户端和数据库Server的一些状态信息。
看源码中的描述:
SqlSession是接口,接口是一种高层次的抽象,你可以认为接口是声明了一种能力。。若是实现了该接口,就拥有了该接口的能力(方法)和特征(属性)。官方的描述是:“你可以通过它执行命令、获取mapper和管理事务”。那也就是说,只要我实现了SqlSession接口,那我就有了同样的能力了。至于它是如何实现发送sql语句,管理事务和获取mapper的,这是后话,后续再说。
我们再来看看,实现了SqlSession的类有哪些?
正如图中所示,DefaultSqlSession是SqlSession接口的默认实现;SqlSessionTemplate也是SqlSession的一种实现。SqlSessionTemplate除了实现了SqlSession接口外,还是实现了下面的接口:
实现了DisposableBean接口,也就代表了SqlSessionTemplate的实例被Bean工厂发现后,会把它们纳入整个生命周期的管理过程中,当BeanFactory被尝试销毁时,Beans的管理者会以回调的方式调用SqlSessionTemplate的destroy()方法。 我们来看看SqlSessionTemplate的destroy()方法的实现:
默认实现是空方法,具体实现你自己可以重写。
2. SqlSessionFactory和SqlSessionFactoryBean
如上图,SqlSessionFactory也是一种抽象定义,其能力(方法 )就是打开一个会话(客户端和数据库Server),而且重载了很多不同的参数,你可以改变这些参数自定义会话过程中的一些默认行为。例如:可以设置自动提交事务或是关闭自动提交;可以设置获取数据库连接的线程的类型(重用,每次新产生等等);也可以获取整个Mybatis的配置信息的Configuration对象实例,关于Configuration的讨论我们下期再说。
SqlSessionFactory的实现也有两种,甚至你可以自定义实现。默认实现是DefaultSqlSessionFactory
DefaultSqlSessionFactory具体实现了SqlSessionFactory接口定义的抽象行为。总而言之,SqlSessionFactory就是生产SqlSession对象的工厂。那也就是说整个Mybatis中,如果只有一个数据库Server要连接,那么只需要一个工厂就够了(只有一个SqlSessionFactory的实例对象),而SqlSession可以自由的被关闭,也就代表SqlSession是需要反复被创建的。上面说到SqlSession是关联到具体数据库连接的,但是如果每次创建和销毁都直接操作物理连接的话,那么这个资源浪费很高,效率很低。请看DefaultSqlSessionFactory的方法:
上图的实现中是有基于连接池技术的。使用数据库连接池时,关闭SqlSession实例 ,其实只是把数据库连接对象(代表物理资源)放回到对象池中,并没有直接销毁,使用连接池技术极大提高了物理资源利用率,缩减了创建物理连接所需的时间、资源等等。
如上图,SqlSessionFactoryBean直接实现了三个接口。实现ApplicationListener代表SqlSessionFactoryBean有能力监控 Application发出的一些事件通知;实现InitializingBean代表SqlSessionFactoryBean中的afterPropertiesSet()方法会在Bean初始化属性完成后立即被调用;实现了FactoryBean代表SqlSessionFactoryBean的实例不再是普通的Bean对象,而是可以产生自己Bean的一种工厂,该工厂产生的Bean同样可以被纳入Spring的生命周期。
正如SqlSessionFactoryBean的名字,它是生产SqlSessionFactory的工厂Bean。
综上所述,SqlSessionFactoryBean是生产SqlSessionFactory的一种工厂Bean;SqlSessionFactory是一种生产SqlSession的工厂;SqlSession是代表数据库连接客户端和数据库Server之间的会话信息;SqlSessionTemplate是SqlSession的一个具体实现。如下图:
说明:图中的蓝色箭头不代表继承的含义。
SqlSessionTemplate是线程安全的在Mybatis-Spring中被广泛使用
SqlSessionTemplate 线程安全的、Spring管理的SqlSession与Spring事务管理一起工作,以确保实际使用的SqlSession与当前Spring事务相关联。此外,它管理会话生命周期,包括根据Spring事务配置在必要时关闭、提交或回滚会话。
模板需要一个SqlSessionFactory来创建作为构造函数参数传递的SqlSessions。还可以构造它,指示要使用的执行程序类型,如果不使用,则将使用在会话工厂中定义的默认执行程序类型。
默认情况下,该模板使用MyBatisExceptionTranslator将MyBatis持久化异常转换为未检查的数据访问异常。
因为SqlSessionTemplate是线程安全的,所以单个实例可以被所有dao共享;这样做还可以节省一些内存。这个模式可以在Spring配置文件中使用