/***
来自DefaultSqlSessionFactory类。
*/
@Override
public SqlSession openSession(boolean autoCommit) {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
}
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);
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();
}
}
下面是来自Confguration类中的创建执行器方法:
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 {//默认的是SIMPLE
executor = new SimpleExecutor(this, transaction);
}
if (cacheEnabled) {//默认配置cacheEnabled=true,所以,会创建简单执行器的包装类
//CachingExecutor执行器
executor = new CachingExecutor(executor);
}
//这一行代码就是为了我们做插件用的,用来代理该对象。我们可以对执行器做功能增强
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
创建的一个简单类型的执行器:使用的本地一级Cache是这个PerpetualCache类型的(最简单的cache),它的wrapper(包装器对象)指向它自己。
/**
创建包装类指行器,它的delegate就是之前创建的基本的执行器,然后将基本执行器的包装类指向它自己。
很典型的一个装饰着设计模式
*/
public CachingExecutor(Executor delegate) {
this.delegate = delegate;
delegate.setExecutorWrapper(this);
}
上面是执行器的类结构图,一般我们的cachingExecutor用于装饰我们的三个基本类型的执行器。
有一点需要说明的是,我们的cacheEnabled改为false后,我们就不需要创建CachingExecutor执行器了,也就不会将查询的值放入二级缓存中的操作和从二级缓存中取值的操作了。
@Override
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
BoundSql boundSql = ms.getBoundSql(parameterObject);
CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}