Mybatis源码分析之SqlSession和Excutor(二)

通过上一篇文章的分析我们,我初步了解了它是如何创建sessionFactory的(地址:Mybatis源码分析之SqlSessionFactory(一)),

今天我们分析下Mybatis如何创建SqlSession( sessionFactory.openSession())和Excutor到底做了什么事情

还是上篇的代码demo

 public static void main(String[] args) throws Exception {
SqlSessionFactory sessionFactory = ;String resource = "configuration.xml";sessionFactory = new SqlSessionFactoryBuilder.build(Resources.getResourceAsReader(resource));SqlSession sqlSession = sessionFactory.openSession;UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
System.out.println(userMapper.findUserById(1));
}

 

1:openSessionFromDataSource

通过openSession最终调用的是 openSessionFromDataSource,源码如下:

 private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = ;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); // may have fetched a connection so lets call closethrow ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);} finally {ErrorContext.instance.reset;}}

说明:ExecutorType(执行器类型)类型有 SIMPLE(默认),REUSE,BATCH,

TransactionIsolationLevel 隔离级别5种

NONE(Connection.TRANSACTION_NONE), READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED), READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED), REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ),

SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE);

通过源码看出首先是从configuration获取environment,接着创建Transaction,

最后通过 configuration.newExecutor创建Executor。

public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == ? defaultExecutorType : executorType;executorType = executorType == ? ExecutorType.SIMPLE : executorType;Executor executor;//根据executorType创建不同的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;}

根据executorType创建对应的Executor,从源码可以看出他有BatchExecutor、ReuseExecutor、CachingExecutor、SimpleExecutor

那么Executor是做什么的呢?

 

2:Executor

Executor是接口,是对于Statement的封装,我们看下Executor,他是真正执行sql的地方。

public interface Executor {
ResultHandler NO_RESULT_HANDLER = ;int update(MappedStatement ms, Object parameter) throws SQLException;
List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
Cursor queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;
List 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);
}

上面源码我可以看到Executor接口定义了update 、query、commit、rollback等方法,他的实现类如下图

Mybatis源码分析之SqlSession和Excutor(二)

我们拿其中的SimpleExecutor类里面的doQuery方法看下源码

 @Override
public List doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
Statement stmt = ;try {Configuration configuration = ms.getConfiguration;StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
//StatementHandler封装了Statement, 让 StatementHandler 去处理stmt = prepareStatement(handler, ms.getStatementLog);return handler.query(stmt, resultHandler);} finally {closeStatement(stmt);}}

我们看看StatementHandler 的一个实现类 PreparedStatementHandler(这也是我们最常用的,封装的是PreparedStatement), 看看它使怎么去处理的:

 @Override
public List query(Statement statement, ResultHandler resultHandler) throws SQLException {String sql = boundSql.getSql;//这个和jdbc一样执行sqlstatement.execute(sql);//结果交给了ResultSetHandler 去处理return resultSetHandler.handleResultSets(statement);}

以上是sql底层执行的基本流程,说的直白一点就是所以sql底层都交给了Excutor,我们将在下一讲中分析上一层的调用,也就是Excutor的上层。

我们继续回到openSessionFromDataSource上面来,通过上面的executor的创建最终是创建

new DefaultSqlSession(configuration, executor, autoCommit);到此我们已经完成了SqlSession的创建,后面我们将分析sqlSession.getMapper 也就是Excutor的上层调用。