无论在 DefaultSqlSessionFactory 还是在 SqlSessionManager 中,session 都是那个 DefaultSqlSession。
SqlSessionManager解决的只是缓存当前线程中的session,实现对session的复用;减少DefaultSqlSessionFactory提供的、每次SQL操作都要重新创建一个新的session实例。
前面几篇文章,从配置文件分析到了session。
一、来看看session是如何配置的:
1、获取session的入口
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
2、配置session
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();
}
}
3、相关的参数
ExecutorType execType = configuration.getDefaultExecutorType();
Executor executor = configuration.newExecutor(tx, execType);
TransactionIsolationLevel level= null;
boolean autoCommit = false;
TransactionFactory transactionFactory= getTransactionFactoryFromEnvironment(environment);
Transaction tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
二、参数的获得
1、ExecutorType
ExecutorType是一个枚举类
public enum ExecutorType {
SIMPLE, REUSE, BATCH
}
在Configuration类中,设定的defaultExecutorType默认值为ExecutorType.SIMPLE
public class Configuration {
...
protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
...
}
ExecutorType的设定,决定session的执行器Executor使用不同的实现类。
Executor executor = configuration.newExecutor(tx, execType);
2、session执行器的设定和封装
ExecutorType决定session执行器的封装策略。
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 {
executor = new SimpleExecutor(this, transaction);
}
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
session执行器executor只能是SimpleExecutor、ReuseExecutor和BatchExecutor三者之一。然后,如果开启了cache,则再装饰CachingExecutor,然后在包装所有插件链的执行器。
executor = (Executor) interceptorChain.pluginAll(executor)
执行器的关系后面单独一篇文章再详细的介绍。
3、TransactionFactory
这个TransactionFactory对应配置文件mybatis-config.xml中environments中的子元素 transactionManager。
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<property name="poolPingQuery" value="SELECT NOW()" />
<property name="poolPingEnabled" value="true" />
dataSource>
environment>
environments>
transactionManager 的取值只有两个:JDBC和MANAGED
如果没有设置,mybatis会使用MANAGED设定session。
从Configuration的构造函数中可以看到这些参数的可选值:
public Configuration() {
typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);
typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
typeAliasRegistry.registerAlias("LRU", LruCache.class);
typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
typeAliasRegistry.registerAlias("WEAK", WeakCache.class);
typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);
typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);
typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);
typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);
languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
languageRegistry.register(RawLanguageDriver.class);
}
JdbcTransactionFactory 创建的是 JdbcTransaction;
ManagedTransactionFactory创建的是ManagedTransaction。
实际上ManagedTransaction很多方法都是空的,通常使用JdbcTransaction。
Transaction tx 被赋值给执行器 executor:
Transaction tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
Executor executor = configuration.newExecutor(tx, execType);
执行器executor和configuration一起生成 DefaultSqlSession。
new DefaultSqlSession(configuration, executor, autoCommit);