mybatis 源码分析之创建SqlSession
mybatis 全中文注释版源码
SqlSession简介
Sqlsession是一次数据库的会话。由于数据库会话连接不是永久的,因此Sqlsession的生命周期也不是永久的,并且在每次访问数据库时都会创建它(在一次会话中,可以提交多次sql,生命周期跟ThreadLocal一致,也就是每个线程都有一个Sqlsession实例对象,所有它是线程不安全的,绝对不能将SqlSession实例的引用放在一个类的静态字段甚至是实例字段中)。的mybatis底层通过SqlsessionFactory的默认实现类DefaultSqlSessionFactory的openSession方法来创建,Sqlsession的默认实现类DefaultSqlSession。
一、DefaultSqlSessionFactory类中的openSession源码解析?
该方法中创建了DefaultSqlSession。创建了 Transaction 对象,并默认将提交方式改为手动提交, 创建 Executor 的默认实现类对象SimpleExecutor。
/**
* Creates an {@link SqlSession} out of a connection or a DataSource
*
* {@link SqlSession} 工厂接口
*
* @author Clinton Begin
*/
public interface SqlSessionFactory {
SqlSession openSession();
SqlSession openSession(boolean autoCommit);
SqlSession openSession(Connection connection);
SqlSession openSession(TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType);
SqlSession openSession(ExecutorType execType, boolean autoCommit);
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType, Connection connection);
Configuration getConfiguration();
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private final Configuration configuration;
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}
———————————————————————————————————————————————————————————————————————————————————————————
//6. 进入openSession方法
@Override
public SqlSession openSession() {
//getDefaultExecutorType()传递的是SimpleExecutor
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
}
———————————————————————————————————————————————————————————————————————————————————————————
// 默认的executor的实现类 定义在configuration中
// protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
configuration.getDefaultExecutorType()的值是SimpleExecutor类
openSessionFromDataSource实际创建对象方法
// 进入openSessionFromDataSource。
//ExecutorType 为Executor的类型,TransactionIsolationLevel为事务隔离级别,autoCommit是否开启事务
//openSession的多个重载方法可以指定获得的SeqSession的Executor类型和事务的处理
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
// 获得 Environment 对象 里面是 <!--environments:运行环境--> 比如当前运行环境 数据库连接配置 事务配置
final Environment environment = configuration.getEnvironment();
// 创建 Transaction 对象
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
// 创建 Executor 对象
final Executor executor = configuration.newExecutor(tx, execType);
// 创建 DefaultSqlSession 对象
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
// 如果发生异常,则关闭 Transaction 对象
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
try {
// 获得是否可以自动提交
boolean autoCommit;
try {
autoCommit = connection.getAutoCommit();
} catch (SQLException e) {
// Failover to true, as most poor drivers
// or databases won't support transactions
autoCommit = true;
}
// 获得 Environment 对象
final Environment environment = configuration.getEnvironment();
// 创建 Transaction 对象
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
final Transaction tx = transactionFactory.newTransaction(connection);
// 创建 Executor 对象
final Executor executor = configuration.newExecutor(tx, execType);
// 创建 DefaultSqlSession 对象
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
// 情况一,创建 ManagedTransactionFactory 对象
if (environment == null || environment.getTransactionFactory() == null) {
return new ManagedTransactionFactory();
}
// 情况二,使用 `environment` 中的
return environment.getTransactionFactory();
}
private void closeTransaction(Transaction tx) {
if (tx != null) {
try {
tx.close();
} catch (SQLException ignore) {
// Intentionally ignore. Prefer previous error.
}
}
}
创建 Transaction 对象
// 获取事务创建工厂
private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
// 情况一,创建 ManagedTransactionFactory 对象
if (environment == null || environment.getTransactionFactory() == null) {
return new ManagedTransactionFactory();
}
// 情况二,使用 `environment` 中的
return environment.getTransactionFactory();
}
// 2创建事务对象 一般是JdbcTransaction 使用该类进行创建
public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
dataSource = ds;
level = desiredLevel;
autoCommit = desiredAutoCommit;
}
创建 Executor 对象
当调用sqlsession去执行具体操作时,底层其实是调用执行器executor的默认实现类SimpleExecutor去执行具体操作。
/**
* 创建 Executor 对象
*
* @param transaction 事务对象
* @param executorType 执行器类型
* @return Executor 对象
*/
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
// 获得执行器类型
executorType = executorType == null ? defaultExecutorType : executorType; // 使用默认
executorType = executorType == null ? ExecutorType.SIMPLE : executorType; // 使用 ExecutorType.SIMPLE
// 创建对应实现的 Executor 对象
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);
}
// 如果开启缓存,创建 CachingExecutor 对象,进行包装 这里指的是开二级缓存 一级缓存是默认开启的
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
// 应用插件
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
创建 DefaultSqlSession 对象
public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
this.configuration = configuration;
this.executor = executor;
// 是否发生数据变更
this.dirty = false;
this.autoCommit = autoCommit;
}
总结
openSession其实内部做了三步操作
1.创建 Transaction实例对象。
2.创建 Executor 对象。
3.创建 DefaultSqlsession实例对象。