在前一篇文章中, 已经解析了配置文件并创建了DefaultSqlSessionFactory对象,那么接下来就是创建会话了:
SqlSession session = sqlSessionFactory.openSession(); // ExecutorType.BATCH
对openSession这个方法,ctrl + alt + B 查看它的实现类,进入DefaultSqlSessionFactory类的openSession() ,它又调用了openSessionFromDataSource方法:
@Override
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
在解析配置文件时,已经 创建了数据源,事务工厂,并放到了全局配置文件Configuration对象中,这里就可以取出来用了
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);
// DefaultSqlSession是线程不安全的,因此每次查询时都创建一个新的DefaultSqlSession;实际使用中,跟spring整合之后,使用线程安全的SqlSessionTemplate
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();
}
}
可以看到,创建会话的过程中,创建了Executor 对象,重点关注下它的创建过程:
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
// 如果不指定executorType,则使用默认的执行器类型SimpleExecutor
executor = new SimpleExecutor(this, transaction);
}
// 二级缓存开关,settings标签中的cacheEnabled值默认是true
if (cacheEnabled) {
// 把SimpleExecutor装饰为用CachingExecutor
executor = new CachingExecutor(executor);
}
// 植入插件,实际上是插件进行代理
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
回到openSessionFromDataSource中,当创建完执行器后,直接返回了一个DefaultSqlSession对象:
return new DefaultSqlSession(configuration, executor, autoCommit);