The creation process of SqlSession in mybatis source code analysis

mybatis之SqlSessionFactory

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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325477343&siteId=291194637