Configuration of mybatis source code analysis
Transaction manager for mybatis source code analysis
The above is the previous analysis, the transaction manager was analyzed in the transaction manager of mybatis source code analysis
SqlSession session = sqlSessionFactory.openSession();
//DefaultSqlSessionFactory里的openSession
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
//根据配置获取环境
final Environment environment = configuration.getEnvironment();
//构建事务工厂
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
//通过事务工厂创建事务Transaction对象
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//创建执行器Executor对象
final Executor executor = configuration.newExecutor(tx, execType);
//根据configuration,executor创建DefaultSqlSession对象
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();
}
}
The transaction manager has been analyzed before, and the executor is analyzed below.
public enum ExecutorType {
SIMPLE, REUSE, BATCH
}
There are only three types of actuators
SIMPLE: ordinary actuator;
REUSE: The executor will reuse prepared statements;
BATCH: The executor will reuse the statement and perform batch updates.
configuration.newExecutor(tx, execType);
//默认执行器类型
protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
//二级缓存的全局开关,默认开启缓存
protected boolean cacheEnabled = true;
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
//executorType为null时executorType=ExecutorType.SIMPLE
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);
}
//当cacheEnabled为true时创建CachingExecutor对象
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
L2 cache switch configuration example
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
After the executor is created
new DefaultSqlSession(configuration, executor, autoCommit);
//DefaultSqlSession构造方法
public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
this.configuration = configuration;
this.executor = executor;
this.dirty = false;
this.autoCommit = autoCommit;
}
So far, the SqlSession has been created. From the previous articles and this article, we can clearly see the whole process from reading the configuration file to the creation of SqlSession. It should be noted that the instance of SqlSession is not thread-safe and cannot be shared, so it is The optimal scope is request or method scope. Each thread should have its own SqlSession instance.