目录
前言
在 上一篇 文章中,我们知道 MyBatis
有四大核心对象,分别是 SqlSessionFactoryBuilder,SqlSessionFactory,SqlSession,Mapper
映射器,而 MyBatis
在和 Spring
整合之后,Spring
会帮助我们管理 SqlSessionFactory、SqlSession、Mapper
映射器这些核心 bean
;在 这一篇 文章中已经阐述了 SqlSessionFactory
对象的产生过程,在本篇文章中就是来阐述 SqlSession
这个对象是如何产生的
SqlSession
对象的产生
在 MyBatis
中我们获取 SqlSession
的实例,实际上使用的都是 new DefaultSqlSession()
的方式,源码在 DefaultSqlSessionFactory
类中如下
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
final Executor executor = configuration.newExecutor(tx, execType);
// MyBatis源码:使用的是 new DefaultSqlSession()的方式,返回一个 SqlSession 对象
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
而 MyBatis
在和 Spring
整合之后,我们是不能使用 new DefaultSqlSession()
的方式来创建 SqlSession
的,因为 DefaultSqlSession
类在 MyBatis
中是线程不安全的
Spring
为了解决类 DefaultSqlSession
线程不安全的问题,为我们提供了一个线程安全的 SqlSessionTemplate
类
SqlSessionTemplate
类登场
SqlSessionTemplate
类简介
该类同我们在 MyBatais
中使用的 DefaultSqlSession
类相同,也都为我们提供了直接操作数据库的一些方法,比如:selectOne(),selectList(),insert(),update(),delete()
等
SqlSessionTemplate
是mybatis-spring
的核心。这个类负责管理MyBatis
的SqlSession
,调用MyBatis
的SQL
方法。SqlSessionTemplate
是线程安全的,可以被多个DAO
所共享使用SqlSessionTemplate
实现了SqlSession
接口,SqlSessionTemplate
通常是被用来替代默认的MyBatis
实现的DefaultSqlSession
, 因为模板可以参与到Spring
的事务中并且被多个注入的映射器类所使用时也是线程安全的
对象 sqlSessionProxy
初始化
我们从 SqlSessionTemplate
类的 selectOne()
方法入手来分析,发现此处使用的是 SqlSession
类型的 sqlSessionProxy
的一个对象,这个对象我们通过名称可以看出它是一个代理类
public class SqlSessionTemplate implements SqlSession, DisposableBean {
private final SqlSessionFactory sqlSessionFactory;
private final ExecutorType executorType;
private final SqlSession sqlSessionProxy;