Executor是跟SqlSession绑定在一起的,每一个SqlSession都拥有一个新的Executor对象,由Configuration创建。代码如下
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; }
Executor类图如下:
Executor分成两大类:
1.BaseExecutor
抽像类,在创建时会根据传过来的ExecutorType创建不同的类,如下:
SimpleExecutor:
每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。(可以是Statement或PrepareStatement对象)
ReuseExecutor:
执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map<String,
Statement>内,供下一次使用。(可以是Statement或PrepareStatement对象),代码如下:
@Override public int doUpdate(MappedStatement ms, Object parameter) throws
SQLException { Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(this, ms,
parameter, RowBounds.DEFAULT, null, null); Statement stmt =
prepareStatement(handler, ms.getStatementLog()); return handler.update(stmt); }
private Statement prepareStatement(StatementHandler handler, Log statementLog)
throws SQLException { Statement stmt; BoundSql boundSql =
handler.getBoundSql(); String sql = boundSql.getSql(); if
(hasStatementFor(sql)) { stmt = getStatement(sql);
applyTransactionTimeout(stmt); } else { Connection connection =
getConnection(statementLog); stmt = handler.prepare(connection,
transaction.getTimeout()); putStatement(sql, stmt); }
handler.parameterize(stmt); return stmt; } private boolean
hasStatementFor(String sql) { try { return statementMap.keySet().contains(sql)
&& !statementMap.get(sql).getConnection().isClosed(); } catch (SQLException e)
{ return false; } } private Statement getStatement(String s) { return
statementMap.get(s); } private void putStatement(String sql, Statement stmt) {
statementMap.put(sql, stmt); } .....
BatchExecutor
:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行
executeBatch()批处理的;BatchExecutor相当于维护了多个桶,每个桶里都装了很多属于自己的SQL,就像苹果蓝里装了很多苹果,番茄蓝里装了很多番茄,最后,再统一倒进仓库
。(可以是Statement或PrepareStatement对象)
2.CachingExecutor
先从缓存中获取查询结果,存在就返回,不存在,再委托给Executor delegate去数据库取,
delegate可以是上面任一的SimpleExecutor、ReuseExecutor、BatchExecutor。代码如下:
public CachingExecutor(Executor delegate) { this.delegate = delegate;
delegate.setExecutorWrapper(this); } .... @Override public int
update(MappedStatement ms, Object parameterObject) throws SQLException {
flushCacheIfRequired(ms); return delegate.update(ms, parameterObject); }
@Override public <E> List<E> 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<E> list =
(List<E>) tcm.getObject(cache, key); if (list == null) { list = delegate.<E>
query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
tcm.putObject(cache, key, list); // issue #578 and #116 } return list; } }
return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key,
boundSql); } ......
热门工具 换一换