最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

mybatis的MappedStatement線程安全探究

 更新時間:2023年08月29日 09:59:37   作者:codecraft  
這篇文章主要為大家介紹了mybatis的MappedStatement線程安全示例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

本文主要研究一下mybatis MappedStatement

MappedStatement

org/apache/ibatis/mapping/MappedStatement.java

public final class MappedStatement {
  private String resource;
  private Configuration configuration;
  private String id;
  private Integer fetchSize;
  private Integer timeout;
  private StatementType statementType;
  private ResultSetType resultSetType;
  private SqlSource sqlSource;
  private Cache cache;
  private ParameterMap parameterMap;
  private List<ResultMap> resultMaps;
  private boolean flushCacheRequired;
  private boolean useCache;
  private boolean resultOrdered;
  private SqlCommandType sqlCommandType;
  private KeyGenerator keyGenerator;
  private String[] keyProperties;
  private String[] keyColumns;
  private boolean hasNestedResultMaps;
  private String databaseId;
  private Log statementLog;
  private LanguageDriver lang;
  private String[] resultSets;
  private boolean dirtySelect;
  //......
}

MappedStatement定義了SqlSource

MappedStatement.Builder

public static class Builder {
    private final MappedStatement mappedStatement = new MappedStatement();
    public Builder(Configuration configuration, String id, SqlSource sqlSource, SqlCommandType sqlCommandType) {
      mappedStatement.configuration = configuration;
      mappedStatement.id = id;
      mappedStatement.sqlSource = sqlSource;
      mappedStatement.statementType = StatementType.PREPARED;
      mappedStatement.resultSetType = ResultSetType.DEFAULT;
      mappedStatement.parameterMap = new ParameterMap.Builder(configuration, "defaultParameterMap", null,
          new ArrayList<>()).build();
      mappedStatement.resultMaps = new ArrayList<>();
      mappedStatement.sqlCommandType = sqlCommandType;
      mappedStatement.keyGenerator = configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType)
          ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;
      String logId = id;
      if (configuration.getLogPrefix() != null) {
        logId = configuration.getLogPrefix() + id;
      }
      mappedStatement.statementLog = LogFactory.getLog(logId);
      mappedStatement.lang = configuration.getDefaultScriptingLanguageInstance();
    }
    //......
  }

MappedStatement定義了一個Builder用于構造MappedStatement

MapperBuilderAssistant

org/apache/ibatis/builder/MapperBuilderAssistant.java

public class MapperBuilderAssistant extends BaseBuilder {
  public MappedStatement addMappedStatement(String id, SqlSource sqlSource, StatementType statementType,
      SqlCommandType sqlCommandType, Integer fetchSize, Integer timeout, String parameterMap, Class<?> parameterType,
      String resultMap, Class<?> resultType, ResultSetType resultSetType, boolean flushCache, boolean useCache,
      boolean resultOrdered, KeyGenerator keyGenerator, String keyProperty, String keyColumn, String databaseId,
      LanguageDriver lang, String resultSets, boolean dirtySelect) {
    if (unresolvedCacheRef) {
      throw new IncompleteElementException("Cache-ref not yet resolved");
    }
    id = applyCurrentNamespace(id, false);
    MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType)
        .resource(resource).fetchSize(fetchSize).timeout(timeout).statementType(statementType)
        .keyGenerator(keyGenerator).keyProperty(keyProperty).keyColumn(keyColumn).databaseId(databaseId).lang(lang)
        .resultOrdered(resultOrdered).resultSets(resultSets)
        .resultMaps(getStatementResultMaps(resultMap, resultType, id)).resultSetType(resultSetType)
        .flushCacheRequired(flushCache).useCache(useCache).cache(currentCache).dirtySelect(dirtySelect);
    ParameterMap statementParameterMap = getStatementParameterMap(parameterMap, parameterType, id);
    if (statementParameterMap != null) {
      statementBuilder.parameterMap(statementParameterMap);
    }
    MappedStatement statement = statementBuilder.build();
    configuration.addMappedStatement(statement);
    return statement;
  }
  //......
}

MapperBuilderAssistant定義了addMappedStatement來專門用于創(chuàng)建和往configuration添加MappedStatement

Configuration

org/apache/ibatis/session/Configuration.java

public class Configuration {
  protected Environment environment;
  protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>(
      "Mapped Statements collection")
          .conflictMessageProducer((savedValue, targetValue) -> ". please check " + savedValue.getResource() + " and "
              + targetValue.getResource());
  //......
  public void addMappedStatement(MappedStatement ms) {
    mappedStatements.put(ms.getId(), ms);
  }
  //......
}

Configuration則定義了以statementId為key,value為MappedStatement的StrictMap

Configuration.StrictMap

protected static class StrictMap<V> extends ConcurrentHashMap<String, V> {
    private static final long serialVersionUID = -4950446264854982944L;
    private final String name;
    private BiFunction<V, V, String> conflictMessageProducer;
    public StrictMap(String name, int initialCapacity, float loadFactor) {
      super(initialCapacity, loadFactor);
      this.name = name;
    }
    public StrictMap(String name, int initialCapacity) {
      super(initialCapacity);
      this.name = name;
    }
    //......
  }

StrictMap繼承了ConcurrentHashMap

SqlSource

org/apache/ibatis/mapping/SqlSource.java

/**
 * Represents the content of a mapped statement read from an XML file or an annotation. It creates the SQL that will be
 * passed to the database out of the input parameter received from the user.
 *
 * @author Clinton Begin
 */
public interface SqlSource {
  BoundSql getBoundSql(Object parameterObject);
}

而SqlSource接口則定義了getBoundSql方法,根據(jù)入?yún)arameterObject來獲取BoundSql
SqlSource有DynamicSqlSource、ProviderSqlSource、RawSqlSource、StaticSqlSource這四種實現(xiàn)

BoundSql

org/apache/ibatis/mapping/BoundSql.java

public class BoundSql {
  private final String sql;
  private final List<ParameterMapping> parameterMappings;
  private final Object parameterObject;
  private final Map<String, Object> additionalParameters;
  private final MetaObject metaParameters;
  //......
}

BoundSql則代表了處理動態(tài)內(nèi)容之后的SQL,該SQL可能還包含占位符

MappedStatement.getBoundSql

public BoundSql getBoundSql(Object parameterObject) {
    BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
    List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
    if (parameterMappings == null || parameterMappings.isEmpty()) {
      boundSql = new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject);
    }
    // check for nested result maps in parameter mappings (issue #30)
    for (ParameterMapping pm : boundSql.getParameterMappings()) {
      String rmId = pm.getResultMapId();
      if (rmId != null) {
        ResultMap rm = configuration.getResultMap(rmId);
        if (rm != null) {
          hasNestedResultMaps |= rm.hasNestedResultMaps();
        }
      }
    }
    return boundSql;
  }

MappedStatement的getBoundSql方法,在從sqlSource獲取到的boundSql的parameterMappings為空時,會根據(jù)自己的ParameterMap的getParameterMappings來重新構建boundSql

DefaultSqlSession

org/apache/ibatis/session/defaults/DefaultSqlSession.java

private <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
    try {
      MappedStatement ms = configuration.getMappedStatement(statement);
      return executor.query(ms, wrapCollection(parameter), rowBounds, handler);
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

DefaultSqlSession的selectList方法則是根據(jù)statement從configuration獲取到MappedStatement然后傳遞給executor

BaseExecutor

org/apache/ibatis/executor/BaseExecutor.java

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

BaseExecutor的query從MappedStatement獲取到了BoundSql,然后一路傳遞下去

小結

mybatis的MappedStatement是根據(jù)statementId從configuration獲取的,這個是在啟動的時候掃描注冊上去的,因此如果通過反射改了MappedStatement會造成全局的影響,也可能有并發(fā)修改的問題;而BoundSql則是每次根據(jù)parameter從MappedStatement獲取的,而MappedStatement則是從sqlSource獲取到的BoundSql,因為每次入?yún)⒍疾煌?,所以這個BoundSql是每次執(zhí)行都會new的,因而如果要在攔截器進行sql改動,改動BoundSql即可。

以上就是mybatis的MappedStatement線程安全探究的詳細內(nèi)容,更多關于mybatis MappedStatement線程安全的資料請關注腳本之家其它相關文章!

相關文章

  • Java實現(xiàn)將Markdown轉換為純文本

    Java實現(xiàn)將Markdown轉換為純文本

    這篇文章主要為大家詳細介紹了兩種在 Java 中實現(xiàn) Markdown 轉純文本的主流方法,文中的示例代碼講解詳細,大家可以根據(jù)需求選擇適合的方案
    2025-03-03
  • Spring AOP方法內(nèi)部調(diào)用不生效的解決方案

    Spring AOP方法內(nèi)部調(diào)用不生效的解決方案

    最近有個需求,統(tǒng)計某個方法的調(diào)用次數(shù),開始使用 Spring AOP 實現(xiàn),后來發(fā)現(xiàn)當方法被內(nèi)部調(diào)用時,切面邏輯將不會生效,所以本文就給大家介紹了Spring AOP方法內(nèi)部調(diào)用不生效的解決方案,需要的朋友可以參考下
    2025-01-01
  • SpringBoot定制JSON響應數(shù)據(jù)返回的示例代碼

    SpringBoot定制JSON響應數(shù)據(jù)返回的示例代碼

    @JsonView 是 Jackson 庫中的一個注解,它允許你定義哪些屬性應該被序列化到 JSON 中,基于不同的“視圖”或“配置”,在本文中,通過了解@JsonView,你將能夠更好地掌握如何在Spring Boot應用中定制JSON數(shù)據(jù)的輸出,需要的朋友可以參考下
    2024-05-05
  • Idea連接GitLab的過程以及創(chuàng)建在gitlab中創(chuàng)建用戶和群組方式

    Idea連接GitLab的過程以及創(chuàng)建在gitlab中創(chuàng)建用戶和群組方式

    本文介紹了如何在IDEA中連接GitLab,首先需安裝GitLab插件并配置SSH免密登錄,接著,創(chuàng)建GitLab個人令牌并在Git中配置,文章還提到了如何在GitLab中創(chuàng)建用戶、群組及設置權限,如Owner、Maintainer、Developer等,并強調(diào)了群組名和人員名稱的命名規(guī)范
    2024-11-11
  • SpringBoot整合Docker實現(xiàn)一次構建到處運行的操作方法

    SpringBoot整合Docker實現(xiàn)一次構建到處運行的操作方法

    本文講解的是 SpringBoot 引入容器化技術 Docker 實現(xiàn)一次構建到處運行,包括鏡像構建、Docker倉庫搭建使用、Docker倉庫可視化UI等內(nèi)容,需要的朋友可以參考下
    2022-10-10
  • 如何在IDEA中查看依賴關系的方法步驟

    如何在IDEA中查看依賴關系的方法步驟

    這篇文章主要介紹了如何在IDEA中查看依賴關系的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • 一文盤點Java中常見內(nèi)存泄漏場景與解決方法

    一文盤點Java中常見內(nèi)存泄漏場景與解決方法

    內(nèi)存泄漏 是指對象 已經(jīng)不再被程序使用,但因為某些原因 無法被垃圾回收器回收,長期占用內(nèi)存,最終可能引發(fā)?OOM,本文會介紹常見的幾類內(nèi)存泄漏場景,大家可以避免一下
    2025-12-12
  • SpringBoot事件發(fā)布與監(jiān)聽超詳細講解

    SpringBoot事件發(fā)布與監(jiān)聽超詳細講解

    今天去官網(wǎng)查看spring boot資料時,在特性中看見了系統(tǒng)的事件及監(jiān)聽章節(jié),所以下面這篇文章主要給大家介紹了關于SpringBoot事件發(fā)布和監(jiān)聽的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-11-11
  • Spring MVC 圖片的上傳和下載功能

    Spring MVC 圖片的上傳和下載功能

    SSM 框架是一種基于Java的Web開發(fā)框架,其中Spring作為控制層、SpringMVC作為視圖層、MyBatis作為持久層,這個框架非常適合Web應用程序的開發(fā),這篇文章主要介紹了Spring MVC 圖片的上傳和下載功能,需要的朋友可以參考下
    2023-03-03
  • SpringBoot+redis配置及測試的方法

    SpringBoot+redis配置及測試的方法

    這篇文章主要介紹了SpringBoot+redis配置及測試的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04

最新評論

濉溪县| 兴海县| 莒南县| 柯坪县| 家居| 正镶白旗| 岑溪市| 登封市| 盐源县| 临颍县| 四平市| 德江县| 长武县| 福鼎市| 洪洞县| 武定县| 天柱县| 绍兴市| 东乡族自治县| 华蓥市| 虎林市| 泸西县| 莆田市| 通辽市| 隆安县| 客服| 青岛市| 旬邑县| 庐江县| 昂仁县| 即墨市| 衡阳县| 乌恰县| 石家庄市| 钟祥市| 合阳县| 如皋市| 长垣县| 洛扎县| 昌平区| 乳源|