executor包執(zhí)行器功能
Executor
接口基于以下方法可以完成增,刪,改查以及事務處理等操作。事實上,mybatis中的所有數(shù)據(jù)庫操作是通過調(diào)用這些方法實現(xiàn)的。
public interface Executor { ? ? ResultHandler NO_RESULT_HANDLER = null; ? ? // 數(shù)據(jù)更新操作,其中數(shù)據(jù)的增加、刪除、更新均可由該方法實現(xiàn) ? int update(MappedStatement ms, Object parameter) throws SQLException; ? // 數(shù)據(jù)查詢操作,返回結(jié)果為列表形式 ? <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException; ? // 數(shù)據(jù)查詢操作,返回結(jié)果為列表形式 ? /** ? ?* 執(zhí)行查詢操作 ? ?* @param ms 映射語句對象 ? ?* @param parameter 參數(shù)對象 ? ?* @param rowBounds 翻頁限制 ? ?* @param resultHandler 結(jié)果處理器 ? ?* @param <E> 輸出結(jié)果類型 ? ?* @return 查詢結(jié)果 ? ?* @throws SQLException ? ?*/ ? <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException; ? // 數(shù)據(jù)查詢操作,返回結(jié)果為游標形式 ? <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; ? // 創(chuàng)建當前查詢的緩存鍵值 ? 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(); ? // 關(guān)閉執(zhí)行器 ? void close(boolean forceRollback); ? // 判斷執(zhí)行器是否關(guān)閉 ? boolean isClosed(); ? // 設置執(zhí)行器包裝 ? void setExecutorWrapper(Executor executor); ? }
BaseExecutor
是一個抽象類,并用到了模板模式,實現(xiàn)了其子類的一些共有的基礎功能,而將與子類直接相關(guān)的操作交給子類處理。
public abstract class BaseExecutor implements Executor { ? ? private static final Log log = LogFactory.getLog(BaseExecutor.class); ? ? protected Transaction transaction; ? protected Executor wrapper; ? ? protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads; ? // 查詢操作的結(jié)果緩存 ? protected PerpetualCache localCache; ? // Callable查詢的輸出參數(shù)緩存 ? protected PerpetualCache localOutputParameterCache; ? protected Configuration configuration; ? ? protected int queryStack; ? private boolean closed; ? ? ? ? ? /** ? ?* 更新數(shù)據(jù)庫數(shù)據(jù),INSERT/UPDATE/DELETE三種操作都會調(diào)用該方法 ? ?* @param ms 映射語句 ? ?* @param parameter 參數(shù)對象 ? ?* @return 數(shù)據(jù)庫操作結(jié)果 ? ?* @throws SQLException ? ?*/ ? @Override ? public int update(MappedStatement ms, Object parameter) throws SQLException { ? ? ErrorContext.instance().resource(ms.getResource()) ? ? ? ? ? ? .activity("executing an update").object(ms.getId()); ? ? if (closed) { ? ? ? // 執(zhí)行器已經(jīng)關(guān)閉 ? ? ? throw new ExecutorException("Executor was closed."); ? ? } ? ? // 清理本地緩存 ? ? clearLocalCache(); ? ? // 返回調(diào)用子類進行操作 ? ? return doUpdate(ms, parameter); ? } ? ?? ? ? /** ? ?* 執(zhí)行查詢操作 ? ?* @param ms 映射語句對象 ? ?* @param parameter 參數(shù)對象 ? ?* @param rowBounds 翻頁限制 ? ?* @param resultHandler 結(jié)果處理器 ? ?* @param <E> 輸出結(jié)果類型 ? ?* @return 查詢結(jié)果 ? ?* @throws SQLException ? ?*/ ? @Override ? public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { ? ? BoundSql boundSql = ms.getBoundSql(parameter); ? ? // 生成緩存的鍵 ? ? CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql); ? ? return query(ms, parameter, rowBounds, resultHandler, key, boundSql); ? } ? ? /** ? ?* 查詢數(shù)據(jù)庫中的數(shù)據(jù) ? ?* @param ms 映射語句 ? ?* @param parameter 參數(shù)對象 ? ?* @param rowBounds 翻頁限制條件 ? ?* @param resultHandler 結(jié)果處理器 ? ?* @param key 緩存的鍵 ? ?* @param boundSql 查詢語句 ? ?* @param <E> 結(jié)果類型 ? ?* @return 結(jié)果列表 ? ?* @throws SQLException ? ?*/ ? @SuppressWarnings("unchecked") ? @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) { ? ? ? // 執(zhí)行器已經(jīng)關(guān)閉 ? ? ? throw new ExecutorException("Executor was closed."); ? ? } ? ? if (queryStack == 0 && ms.isFlushCacheRequired()) { // 新的查詢棧且要求清除緩存 ? ? ? // 清除一級緩存 ? ? ? clearLocalCache(); ? ? } ? ? List<E> list; ? ? try { ? ? ? queryStack++; ? ? ? // 嘗試從本地緩存獲取結(jié)果 ? ? ? list = resultHandler == null ? (List<E>) localCache.getObject(key) : null; ? ? ? if (list != null) { ? ? ? ? // 本地緩存中有結(jié)果,則對于CALLABLE語句還需要綁定到IN/INOUT參數(shù)上 ? ? ? ? handleLocallyCachedOutputParameters(ms, key, parameter, boundSql); ? ? ? } else { ? ? ? ? // 本地緩存沒有結(jié)果,故需要查詢數(shù)據(jù)庫 ? ? ? ? list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql); ? ? ? } ? ? } finally { ? ? ? queryStack--; ? ? } ? ? if (queryStack == 0) { ? ? ? // 懶加載操作的處理 ? ? ? for (DeferredLoad deferredLoad : deferredLoads) { ? ? ? ? deferredLoad.load(); ? ? ? } ? ? ? deferredLoads.clear(); ? ? ? // 如果本地緩存的作用域為STATEMENT,則立刻清除本地緩存 ? ? ? if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) { ? ? ? ? clearLocalCache(); ? ? ? } ? ? } ? ? return list; ? } ? ?? ? ? /** ? ?* 生成查詢的緩存的鍵 ? ?* @param ms 映射語句對象 ? ?* @param parameterObject 參數(shù)對象 ? ?* @param rowBounds 翻頁限制 ? ?* @param boundSql 解析結(jié)束后的SQL語句 ? ?* @return 生成的鍵值 ? ?*/ ? @Override ? public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) { ? ? if (closed) { ? ? ? throw new ExecutorException("Executor was closed."); ? ? } ? ? // 創(chuàng)建CacheKey,并將所有查詢參數(shù)依次更新寫入 ? ? CacheKey cacheKey = new CacheKey(); ? ? cacheKey.update(ms.getId()); ? ? cacheKey.update(rowBounds.getOffset()); ? ? cacheKey.update(rowBounds.getLimit()); ? ? cacheKey.update(boundSql.getSql()); ? ? List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); ? ? TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry(); ? ? for (ParameterMapping parameterMapping : parameterMappings) { ? ? ? if (parameterMapping.getMode() != ParameterMode.OUT) { ? ? ? ? Object value; ? ? ? ? String propertyName = parameterMapping.getProperty(); ? ? ? ? if (boundSql.hasAdditionalParameter(propertyName)) { ? ? ? ? ? value = boundSql.getAdditionalParameter(propertyName); ? ? ? ? } else if (parameterObject == null) { ? ? ? ? ? value = null; ? ? ? ? } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { ? ? ? ? ? value = parameterObject; ? ? ? ? } else { ? ? ? ? ? MetaObject metaObject = configuration.newMetaObject(parameterObject); ? ? ? ? ? value = metaObject.getValue(propertyName); ? ? ? ? } ? ? ? ? cacheKey.update(value); ? ? ? } ? ? } ? ? if (configuration.getEnvironment() != null) { ? ? ? cacheKey.update(configuration.getEnvironment().getId()); ? ? } ? ? return cacheKey; ? } }
BaseExecutor有四個實現(xiàn)類:
CloseExecutor
:僅表明自身已經(jīng)關(guān)閉的執(zhí)行器,沒有其他實際功能SimpleExecutor
: 一個最為簡單的執(zhí)行器BatchExecutor
:支持批量執(zhí)行功能的執(zhí)行器ReuseExecutor
: 支持Statement對象復用的執(zhí)行器。
SimpleExecutor
,BatchExecutor
,ReuseExecutor
這三個執(zhí)行器的選擇是在mybatis
的配置文件中進行的,可選的值由session
包中的ExecutorType定義,這三個執(zhí)行器主要基于StatementHandler完成創(chuàng)建Statement對象,綁定參數(shù)等工作。
到此這篇關(guān)于executor包執(zhí)行器功能的文章就介紹到這了,更多相關(guān)executor包內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中Formatter和Converter用法和區(qū)別小結(jié)
本文主要介紹了SpringBoot中Formatter和Converter用法和區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-07-07通過Spring Boot + Mybatis + Redis快速搭建現(xiàn)代化Web項目
本篇文章介紹了如何通過Spring Boot、Mybatis以及Redis快速搭建一個現(xiàn)代化的Web項目,并且同時介紹了如何在Spring Boot下優(yōu)雅地書寫單元測試來保證我們的代碼質(zhì)量。具體內(nèi)容詳情大家通過本文學習下吧2017-12-122024.1.2 安裝JDK和Eclipse并配置java編譯環(huán)境的過程
這篇文章主要介紹了2024.1.2 安裝JDK和Eclipse并配置java編譯環(huán)境,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-01-01java實現(xiàn)Img與PDF相互轉(zhuǎn)換
這篇文章主要為大家詳細介紹了java實現(xiàn)Img與PDF相互轉(zhuǎn)換的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05