一、引言
由上一篇知,手动使用Mybatis的四个步骤:
获取SqlSessionFactory对象
获取sqlSession对象
获取接口的代理对象(MapperProxy)
执行增删改查方法
上一篇中MyBatis工作原理源码分析(一),详细分析了第一步SqlSessionFactory的初始化过程,下面在此基础上,来分析SqlSession对象的获取。
二、获取SqlSession对象源码分析
当获取到SqlSessionFactory之后,就可以通过SqlSessionFactory去获取SqlSession对象。下面来分析一下源码:
//2、获取sqlSession对象
SqlSession openSession = sqlSessionFactory.openSession();
1、调用openSession()方法,获取sqlSession对象
@Override
public SqlSession openSession() {
//从数据源中拿openSession,参数是得到默认的ExecutorType,默认是Simple,即简单的执行器
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
2、调用openSessionFromDataSource()方法
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
//通过Confuguration对象去获取Mybatis中的Environment对象,该包含了数据源和事务的配置
final Environment environment = configuration.getEnvironment();
//获取一些信息,创建事务
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//从表面上来看,咱们是用sqlSession在执行sql语句, 实际呢,其实是通过excutor执行,excutor是对于Statement的封装
final Executor executor = configuration.newExecutor(tx, execType);
//关键在这,创建了一个DefaultSqlSession对象!!!!!!
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
} finally {
ErrorContext.instance().reset();
}
}
3、根据Executor在全局配置中的类型,创建出SimpleExecutor/ReuseExecutor/BatchExecutor
//根据ExecutorType类型,创建一个Executor
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
//创建一个BatchExecutor
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
//创建一个ReuseExecutor
executor = new ReuseExecutor(this, transaction);
} else {
//创建一个SimpleExecutor
executor = new SimpleExecutor(this, transaction);
}
//如果二级缓存如果开启,则创建一个CachingExecutor
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
//很重要!很重要!很重要!每一个Executor创建都要走这一步。
executor = (Executor) interceptorChain.pluginAll(executor);
//返回包装后的Executor
return executor;
}
4、获取到所有拦截器,调用每一个拦截器的plugin方法,重新将executor包装一下
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
说明:Executor是一个接口,里面有增删改查的方法,源码如下。
public interface Executor {
ResultHandler NO_RESULT_HANDLER = null;
int update(MappedStatement ms, Object parameter) throws SQLException;
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
<E> Cursor<E> queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;
List<BatchResult> flushStatements() throws SQLException;
void commit(boolean required) throws SQLException;
void rollback(boolean required) throws SQLException;
CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);
boolean isCached(MappedStatement ms, CacheKey key);
void clearLocalCache();
void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType);
Transaction getTransaction();
void close(boolean forceRollback);
boolean isClosed();
void setExecutorWrapper(Executor executor);
}
三、小结
下面是上面分析的时序图:
总结:
1、返回SqlSession的实现类DefaultSqlSession对象,它里面包含了Executor和Configuration;
2、Executor会在这一步被创建,用于执行Sql。