executor包執(zhí)行器功能
Executor接口基于以下方法可以完成增,刪,改查以及事務處理等操作。事實上,mybatis中的所有數據庫操作是通過調用這些方法實現的。
public interface Executor {
?
? ResultHandler NO_RESULT_HANDLER = null;
?
? // 數據更新操作,其中數據的增加、刪除、更新均可由該方法實現
? int update(MappedStatement ms, Object parameter) throws SQLException;
? // 數據查詢操作,返回結果為列表形式
? <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
? // 數據查詢操作,返回結果為列表形式
? /**
? ?* 執(zhí)行查詢操作
? ?* @param ms 映射語句對象
? ?* @param parameter 參數對象
? ?* @param rowBounds 翻頁限制
? ?* @param resultHandler 結果處理器
? ?* @param <E> 輸出結果類型
? ?* @return 查詢結果
? ?* @throws SQLException
? ?*/
? <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
? // 數據查詢操作,返回結果為游標形式
? <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();
? // 關閉執(zhí)行器
? void close(boolean forceRollback);
? // 判斷執(zhí)行器是否關閉
? boolean isClosed();
? // 設置執(zhí)行器包裝
? void setExecutorWrapper(Executor executor);
?
}BaseExecutor是一個抽象類,并用到了模板模式,實現了其子類的一些共有的基礎功能,而將與子類直接相關的操作交給子類處理。
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;
? // 查詢操作的結果緩存
? protected PerpetualCache localCache;
? // Callable查詢的輸出參數緩存
? protected PerpetualCache localOutputParameterCache;
? protected Configuration configuration;
?
? protected int queryStack;
? private boolean closed;
?
?
?
?
? /**
? ?* 更新數據庫數據,INSERT/UPDATE/DELETE三種操作都會調用該方法
? ?* @param ms 映射語句
? ?* @param parameter 參數對象
? ?* @return 數據庫操作結果
? ?* @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í)行器已經關閉
? ? ? throw new ExecutorException("Executor was closed.");
? ? }
? ? // 清理本地緩存
? ? clearLocalCache();
? ? // 返回調用子類進行操作
? ? return doUpdate(ms, parameter);
? }
?
??
?
? /**
? ?* 執(zhí)行查詢操作
? ?* @param ms 映射語句對象
? ?* @param parameter 參數對象
? ?* @param rowBounds 翻頁限制
? ?* @param resultHandler 結果處理器
? ?* @param <E> 輸出結果類型
? ?* @return 查詢結果
? ?* @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);
? }
?
? /**
? ?* 查詢數據庫中的數據
? ?* @param ms 映射語句
? ?* @param parameter 參數對象
? ?* @param rowBounds 翻頁限制條件
? ?* @param resultHandler 結果處理器
? ?* @param key 緩存的鍵
? ?* @param boundSql 查詢語句
? ?* @param <E> 結果類型
? ?* @return 結果列表
? ?* @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í)行器已經關閉
? ? ? throw new ExecutorException("Executor was closed.");
? ? }
? ? if (queryStack == 0 && ms.isFlushCacheRequired()) { // 新的查詢棧且要求清除緩存
? ? ? // 清除一級緩存
? ? ? clearLocalCache();
? ? }
? ? List<E> list;
? ? try {
? ? ? queryStack++;
? ? ? // 嘗試從本地緩存獲取結果
? ? ? list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
? ? ? if (list != null) {
? ? ? ? // 本地緩存中有結果,則對于CALLABLE語句還需要綁定到IN/INOUT參數上
? ? ? ? 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();
? ? ? }
? ? ? deferredLoads.clear();
? ? ? // 如果本地緩存的作用域為STATEMENT,則立刻清除本地緩存
? ? ? if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
? ? ? ? clearLocalCache();
? ? ? }
? ? }
? ? return list;
? }
?
??
?
? /**
? ?* 生成查詢的緩存的鍵
? ?* @param ms 映射語句對象
? ?* @param parameterObject 參數對象
? ?* @param rowBounds 翻頁限制
? ?* @param boundSql 解析結束后的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,并將所有查詢參數依次更新寫入
? ? 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有四個實現類:
CloseExecutor:僅表明自身已經關閉的執(zhí)行器,沒有其他實際功能SimpleExecutor: 一個最為簡單的執(zhí)行器BatchExecutor:支持批量執(zhí)行功能的執(zhí)行器ReuseExecutor: 支持Statement對象復用的執(zhí)行器。
SimpleExecutor,BatchExecutor,ReuseExecutor 這三個執(zhí)行器的選擇是在mybatis的配置文件中進行的,可選的值由session包中的ExecutorType定義,這三個執(zhí)行器主要基于StatementHandler完成創(chuàng)建Statement對象,綁定參數等工作。
到此這篇關于executor包執(zhí)行器功能的文章就介紹到這了,更多相關executor包內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
springboot實現指定mybatis中mapper文件掃描路徑
這篇文章主要介紹了springboot實現指定mybatis中mapper文件掃描路徑方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
Java中比較器Comparator和Comparable的區(qū)別
這篇文章主要介紹了Java中比較器Comparator和Comparable的區(qū)別,我們在使用?Collections.sort()對鏈表進行排序時,常常需要根據不同情況自定義排序規(guī)則,今天我們來看看比較器之間的區(qū)別,需要的朋友可以參考下2023-08-08
解決spring中redistemplate不能用通配符keys查出相應Key的問題
這篇文章主要介紹了解決spring中redistemplate不能用通配符keys查出相應Key的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11

