CachingExecutor
@Override
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
//獲取sql語句信息,包括佔位符,參數等信息
BoundSql boundSql = ms.getBoundSql(parameterObject);
//拼裝緩存的key值
CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
@Override
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
throws SQLException {
//從MappedStatement中獲取二級緩存
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) {
//二級緩存爲空,纔會調用BaseExecutor.query
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);
}
BaseExecutor
上面的 query 會到下面這個方法來
@Override
public <E> List<E> 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());
if (closed) {//檢查當前executor是否關閉
throw new ExecutorException("Executor was closed.");
}
if (queryStack == 0 && ms.isFlushCacheRequired()) {//非嵌套查詢,並且FlushCache配置爲true,則需要清空一級緩存
clearLocalCache();
}
List<E> list;
try {
queryStack++;//查詢層次加一
list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;//從緩存拿
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) {//如果當前sql的一級緩存配置爲STATEMENT,查詢完既清空一集緩存
// issue #482
clearLocalCache();
}
}
return list;
}