Executor 执行器使用
配置
使用
String resource = "mybatis-config.xml";
//将XML配置文件构建为Configuration配置类
Reader reader = Resources.getResourceAsReader(resource);
// 通过加载配置文件流构建一个SqlSessionFactory 解析xml文件
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
Configuration configuration = sqlSessionFactory.getConfiguration();
Connection connection = configuration.getEnvironment().getDataSource().getConnection();
Transaction transaction = configuration.getEnvironment().getTransactionFactory().newTransaction(connection);
SimpleExecutor simpleExecutor = new SimpleExecutor(configuration, transaction);
//ReuseExecutor executor = new ReuseExecutor(configuration, transaction);
MappedStatement mappedStatement = configuration.getMappedStatement("com.mx.mapper.UserMapper.selectById");
List
Executor
baseExecutor(一级缓存)batchExecutor(批量执行器)ReUseExecutor(可重用的)SimpleExecutor简单的CacheExecutor(加入了二级缓存)
源码 DefaultSqlSession.openSession() 数据源 执行器
SqlSession session = sqlSessionFactory.openSession();
openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
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); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
创建一个sql执行器
默认 ExecutorType.SIMPLE
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 {
//简单的sql执行器对象
executor = new SimpleExecutor(this, transaction);
}
//判断mybatis的全局配置文件是否开启缓存
if (cacheEnabled) {
//把当前的简单的执行器包装成一个CachingExecutor
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
执行操作 User user = session.selectOne("com.mx.mapper.UserMapper.selectById", 1);
@Override publicList selectList(String statement, Object parameter, RowBounds rowBounds) { try { MappedStatement ms = configuration.getMappedStatement(statement); return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }
转发给执行器操作 executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER)
@Override publicList query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { BoundSql boundSql = ms.getBoundSql(parameterObject); CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql); return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); }
首先二级缓存查
@Override publicList query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { Cache cache = ms.getCache(); if (cache != null) { //判断是否需要刷新缓存 flushCacheIfRequired(ms); if (ms.isUseCache() && resultHandler == null) { ensureNoOutParams(ms, boundSql); @SuppressWarnings("unchecked") List list = (List ) tcm.getObject(cache, key); if (list == null) { //通过查询数据库去查询 list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); //加入到二级缓存中 tcm.putObject(cache, key, list); // issue #578 and #116 } return list; } } //没有整合二级缓存,直接去查询 return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); }
一级缓存delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
PerpetualCache localCache 一级缓存
@Override publicList query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId()); //已经关闭,则抛出 ExecutorException 异常 if (closed) { throw new ExecutorException("Executor was closed."); } // <2> 清空本地缓存,如果 queryStack 为零,并且要求清空本地缓存。 if (queryStack == 0 && ms.isFlushCacheRequired()) { clearLocalCache(); } List list; try { // <4.1> 从一级缓存中,获取查询结果 queryStack++; list = resultHandler == null ? (List ) localCache.getObject(key) : null; // <4.2> 获取到,则进行处理 if (list != null) { //处理存过的 handleLocallyCachedOutputParameters(ms, key, parameter, boundSql); } else { // 获得不到,则从数据库中查询 list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql); } } finally { queryStack--; } if (queryStack == 0) { for (DeferredLoad deferredLoad : deferredLoads) { deferredLoad.load(); } // issue #601 deferredLoads.clear(); if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) { // issue #482 clearLocalCache(); } } return list; }
二级缓存-》一级缓存都查不到到数据库查queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql)
SimpleExecutor.doQuery
@Override publicList doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { Statement stmt = null; try { Configuration configuration = ms.getConfiguration(); StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql); // 拿到连接和statement stmt = prepareStatement(handler, ms.getStatementLog()); return handler.query(stmt, resultHandler); } finally { closeStatement(stmt); } }



