成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

什么是MybatisExcuter框架

今天就跟大家聊聊有關(guān)什么是Mybatis Excuter框架,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

站在用戶的角度思考問題,與客戶深入溝通,找到遜克網(wǎng)站設(shè)計(jì)與遜克網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名與空間、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋遜克地區(qū)。

Excuter框架類圖

什么是Mybatis Excuter框架

BaseExecutor

在BaseExecutor定義了Executor的基本實(shí)現(xiàn),如查詢一級緩存,事務(wù)處理等不變的部分,操作數(shù)據(jù)庫等變化部分由子類實(shí)現(xiàn),使用了模板設(shè)計(jì)模式,下面我們來看下查詢方法的源碼:

@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);
}

/**
 * 所有的查詢操作最后都是由該方法來處理的
 */
@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) {
    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) {
      // 處理存儲(chǔ)過程的OUT參數(shù)
      handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
    } else {
      // 緩存未命中,查詢數(shù)據(jù)庫
      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;
}

private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
  List<E> list;
  // 添加緩存占位符
  localCache.putObject(key, EXECUTION_PLACEHOLDER);
  try {
    list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
  } finally {
    // 刪除緩存占位符
    localCache.removeObject(key);
  }
  // 將查詢結(jié)果添加到本地緩存
  localCache.putObject(key, list);
  if (ms.getStatementType() == StatementType.CALLABLE) {
    // 如果是存儲(chǔ)過程則,緩存參數(shù)
    localOutputParameterCache.putObject(key, parameter);
  }
  return list;
}

什么是Mybatis Excuter框架

queryFromDatabase() 方法中,我們可以看到doQuery使用的是模板方法,具體邏輯是由子類來實(shí)現(xiàn)的,這樣做的好處是,子類只關(guān)心程序變化的部分,其他不變的部分由父類實(shí)現(xiàn)。提高了代碼的復(fù)用性和代碼的擴(kuò)展性。

SimpleExecutor

普通的執(zhí)行器,Mybatis的默認(rèn)使用該執(zhí)行器,每次新建Statement。我們還是來看下查詢方法的源碼:

@Override
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
  Statement stmt = null;
  try {
    // 獲取Mybatis配置類
    Configuration configuration = ms.getConfiguration();
    // 根據(jù)配置類獲取StatementHandler
    StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
    // 創(chuàng)建Statement
    stmt = prepareStatement(handler, ms.getStatementLog());
    return handler.query(stmt, resultHandler);
  } finally {
    closeStatement(stmt);
  }
}

private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
  Statement stmt;
  // 獲取Connection連接
  Connection connection = getConnection(statementLog);
  // 根據(jù)Connection獲取Statement
  stmt = handler.prepare(connection, transaction.getTimeout());
  // 設(shè)置參數(shù)
  handler.parameterize(stmt);
  return stmt;
}

通過 stmt = handler.prepare(connection, transaction.getTimeout());方法我們可以看出每次是新建Statement。

ReuseExecutor

可以重用的執(zhí)行器,復(fù)用的是Statement,內(nèi)部以sql語句為key使用一個(gè)Map將Statement對象緩存起來,只要連接不斷開,那么Statement就可以重用。

因?yàn)槊恳粋€(gè)新的SqlSession都有一個(gè)新的Executor對象,所以我們緩存在ReuseExecutor上的Statement的作用域是同一個(gè)SqlSession,所以其實(shí)這個(gè)緩存用處其實(shí)并不大。我們直接看下獲取Statement源碼,其他部分和SimpleExecutor查詢方法一樣。

private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
  Statement stmt;
  BoundSql boundSql = handler.getBoundSql();
  String sql = boundSql.getSql();
  if (hasStatementFor(sql)) {
    // 獲取復(fù)用的Statement
    stmt = getStatement(sql);
    applyTransactionTimeout(stmt);
  } else {
    // 新建Statement,并緩存
    Connection connection = getConnection(statementLog);
    stmt = handler.prepare(connection, transaction.getTimeout());
    putStatement(sql, stmt);
  }
  handler.parameterize(stmt);
  return stmt;
}

private boolean hasStatementFor(String sql) {
  try {
    // 根據(jù)sql判斷是否緩存了Statement,并判斷Connection是否關(guān)閉
    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);
}

什么是Mybatis Excuter框架

BatchExecutor

批處理執(zhí)行器,通過封裝jdbc的 statement.addBatch(String sql) 以及 statement.executeBatch(); 來實(shí)現(xiàn)的批處理。該執(zhí)行器的事務(wù)只能是手動(dòng)提交模式。

我們平時(shí)執(zhí)行批量的處理是一般還可以使用sql拼接的方式。

執(zhí)行批量更新時(shí)建議一次不要更新太多數(shù)據(jù),如果更新數(shù)據(jù)量比較大時(shí)可以分段執(zhí)行。

CachingExecutor

如果開啟了二級緩存那么Mybatis會(huì)使用CachingExecutor執(zhí)行器,CachingExecutor使用了裝飾器模式。

@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) {
        // 調(diào)用被裝飾則的方法
        list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
        // 將數(shù)據(jù)放入緩存
        tcm.putObject(cache, key, list); // issue #578 and #116
      }
      return list;
    }
  }
  // 沒找到緩存,直接調(diào)用被裝飾則的方法
  return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}

通過源碼我們發(fā)現(xiàn),整個(gè)查詢流程變成 了 L2 -> L1 -> DB。CachingExecutor的查詢流程,增加了二級緩存的查詢操作。

我們在實(shí)際使用緩存過程中一般很少使用Mybatis的二級緩存,如果想做二級緩存,建議直接在service層面使用第三方緩存框架,推薦使用為監(jiān)控而生的多級緩存框架 layering-cache,使用更方便靈活,查詢流程是 L1 -> L2 -> DB。

BaseExecutor:使用了模板方法模式,定義了Executor的基本實(shí)現(xiàn),它是一個(gè)抽象類,不能直接對外提供服務(wù)。

SimpleExecutor:普通的執(zhí)行器,Mybatis的默認(rèn)使用該執(zhí)行器,每次新建Statement。

ReuseExecutor:可以重用Statement的執(zhí)行器,但是這個(gè)Statement緩存只在一次SqlSession中有效,我們平時(shí)生少有在一次SqlSession中進(jìn)行多次一樣的查詢操作,所以性能提升并不大。

BatchExecutor:批處理執(zhí)行器

CachingExecutor:二級緩存執(zhí)行器,使用裝飾器模式,整個(gè)查詢流程變成 了 L2 -> L1 -> DB。建議直接使用第三方緩存架,如:為監(jiān)控而生的多級緩存框架 layering-cache。

看完上述內(nèi)容,你們對什么是Mybatis Excuter框架有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。

文章題目:什么是MybatisExcuter框架
文章源于:http://jinyejixie.com/article48/gdhoep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、全網(wǎng)營銷推廣、ChatGPT、電子商務(wù)、、網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
九台市| 依兰县| 安仁县| 南丰县| 中超| 云和县| 华容县| 德兴市| 嘉鱼县| 德兴市| 晋江市| 大安市| 宝应县| 宁晋县| 禄劝| 黔西县| 保靖县| 南充市| 东乡族自治县| 芦山县| 临安市| 潼关县| 蒲江县| 黄骅市| 小金县| 沈阳市| 卫辉市| 白河县| 郑州市| 无锡市| 江津市| 简阳市| 板桥市| 濮阳县| 庆云县| 灵璧县| 巫溪县| 防城港市| 顺义区| 涞水县| 繁峙县|