创建 sqlSession
创建 openSession 对象
- 当获取 SqlSessionFactory 之后,就可以开始获取 SqlSession 对象
public class MybatisTest {
@Test
public void test1() throws IOException {
...
SqlSession sqlSession = sqlSessionFactory.openSession();
...
sqlSession.close();
}
}
- 其中,openSession() 支持很多种参数类型定义,主要是判断是否进行事务自动提交、数据库连接、执行器类型选择、事务隔离级别
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ae3bcdd76cd399247cef450b10d197c0.png)
- 下面是走默认构造函数
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private final Configuration configuration;
...
@Override
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
}
- 其中,getDefaultExecutorType() 返回默认执行器类型,也就是
SIMPLE
public class Configuration {
...
protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
...
public ExecutorType getDefaultExecutorType() {
return defaultExecutorType;
}
}
- 执行器类型包含
SIMPLE
、REUSE
、BATCH
,实现的类图如图下所示
- BaseExecutor:基础执行器,封装了子类的公共方法,包括一级缓存、延迟加载、回滚、关闭等功能
- SimpleExecutor:简单执行器,每执行一条 sql,都会打开一个 Statement,执行完成后关闭
- ReuseExecutor:重用执行器,相较于 SimpleExecutor 多了 Statement 的缓存功能,其内部维护一个 Map<String, Statement> ,每次编译完成的 Statement 都会进行缓存,不会关闭
- BatchExecutor:批量执行器,基于 JDBC 的 addBatch()、executeBatch() 功能,并且在当前 sql 和上一条 sql 完全一样的时候,重用 Statement,在调用doFlushStatements() 的时候,将数据刷新到数据库
- CachingExecutor:缓存执行器,装饰器模式,在开启缓存的时候。会在上面三种执行器的外面包上 CachingExecutor
- 在 openSessionFromDataSource 中,先拿到 environment 对象,根据 environment 对象里面的配置、包括数据源,创建事务工厂对象。然后根据执行器类型,利用事务管理器创建 executor 对象,最后把 configuration,executor 封装到 DefaultSqlSession 返回
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private final Configuration configuration;
...
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);
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
}
- 在 JdbcTransactionFactory 的 newTransaction() 中,会返回一个 JdbcTransaction 对象,它的底层会通过一个 Connection 对象,进行 commit() 或者 rollback()
public class JdbcTransactionFactory implements TransactionFactory {
...
@Override
public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
return new JdbcTransaction(ds, level, autoCommit);
}
}
- 在使用 sqlsession 时,具体的执行是依赖执行器的,下面看看执行器的创建。根据传入的执行器类型,来对 transaction 进行封装,如果开启了
cacheEnabled
还会利用装饰者模式,对创建的 executor 再包一层,开启缓存。最后还可以使用拦截器插件也再对 executor 进行封装
public class Configuration {
...
protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
protected boolean cacheEnabled = true;
...
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;
}
}
- 总结
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a3ab094e136c3fef8a098f4046c114e7.jpeg)