创建 sqlSession
创建 openSession 对象
当获取 SqlSessionFactory 之后,就可以开始获取 SqlSession 对象
public class MybatisTest {
@Test
public void test1 ( ) throws IOException {
. . .
SqlSession sqlSession = sqlSessionFactory. openSession ( ) ;
. . .
sqlSession. close ( ) ;
}
}
其中,openSession() 支持很多种参数类型定义,主要是判断是否进行事务自动提交、数据库连接、执行器类型选择、事务隔离级别
下面是走默认构造函数
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;
}
}
总结