MyBatis入门源码一:配置解析

一、SqlSessionFactory 的构建:SqlSessionFactoryBuilder#build(…)

看一下我们mybatis-config.xml 配置的内容:
MyBatis入门源码一:配置解析_第1张图片
MyBatis入门源码一:配置解析_第2张图片
MyBatis入门源码一:配置解析_第3张图片

  1. parser.parse(): 解析配置文件

MyBatis入门源码一:配置解析_第4张图片
MyBatis入门源码一:配置解析_第5张图片
解析的内容很多,重点看解析数据源、解析mapper文件

  1. build: 创建DefaultSqlSessionFactory

二、解析数据源

MyBatis入门源码一:配置解析_第6张图片
我们配置文件里面配置的,最终解析成为 JdbcTransactionFactory

接下来看看数据源是怎么解析的?
MyBatis入门源码一:配置解析_第7张图片
我们配置文件里面配置的,最终会解析为PooledDataSourceFactory,里面有个PooledDataSource,里面封装的是我们在配置文件配置的 driver、url、username、password
MyBatis入门源码一:配置解析_第8张图片

当全部解析完成后,最终放到configuration的environment里面去
MyBatis入门源码一:配置解析_第9张图片

三、解析mapper文件

mapper的配置一般有2种,一个是package,一种是resource的方式,很容易理解的,一个要说明mapper package在哪里,一个要说明mapper文件资源在哪里
MyBatis入门源码一:配置解析_第10张图片

我们就按照上面配置的resource方式来看Mybatis是如何解析 mapper文件的
MyBatis入门源码一:配置解析_第11张图片
MyBatis入门源码一:配置解析_第12张图片
MyBatis入门源码一:配置解析_第13张图片
MyBatis入门源码一:配置解析_第14张图片
这里的buildStatementFromContext是用来解析mapper文件里面内容的(已经从mapper文件里面获取到方法),最终会调用到XMLStatementBuilder.parseStatementNode方法
MyBatis入门源码一:配置解析_第15张图片

 /**
   * 解析 xml 中的 select,insert,update,delete 等语句
   */
  public void parseStatementNode() {
    String id = context.getStringAttribute("id");
    String databaseId = context.getStringAttribute("databaseId");

    if (!databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) {
      return;
    }

    String nodeName = context.getNode().getNodeName();
    SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
    boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
    boolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);
    boolean useCache = context.getBooleanAttribute("useCache", isSelect);
    boolean resultOrdered = context.getBooleanAttribute("resultOrdered", false);

    // Include Fragments before parsing
    XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
    includeParser.applyIncludes(context.getNode());

    String parameterType = context.getStringAttribute("parameterType");
    Class<?> parameterTypeClass = resolveClass(parameterType);

    String lang = context.getStringAttribute("lang");
    LanguageDriver langDriver = getLanguageDriver(lang);

    // Parse selectKey after includes and remove them.
    processSelectKeyNodes(id, parameterTypeClass, langDriver);

    // Parse the SQL (pre:  and  were parsed and removed)
    KeyGenerator keyGenerator;
    String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;
    keyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);
    if (configuration.hasKeyGenerator(keyStatementId)) {
      keyGenerator = configuration.getKeyGenerator(keyStatementId);
    } else {
      keyGenerator = context.getBooleanAttribute("useGeneratedKeys",
          configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))
          ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;
    }

    // todo 在这里解析sql内容
    SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
    StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
    Integer fetchSize = context.getIntAttribute("fetchSize");
    Integer timeout = context.getIntAttribute("timeout");
    String parameterMap = context.getStringAttribute("parameterMap");
    String resultType = context.getStringAttribute("resultType");
    Class<?> resultTypeClass = resolveClass(resultType);
    String resultMap = context.getStringAttribute("resultMap");
    String resultSetType = context.getStringAttribute("resultSetType");
    ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);
    if (resultSetTypeEnum == null) {
      resultSetTypeEnum = configuration.getDefaultResultSetType();
    }
    String keyProperty = context.getStringAttribute("keyProperty");
    String keyColumn = context.getStringAttribute("keyColumn");
    String resultSets = context.getStringAttribute("resultSets");

    builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
        fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
        resultSetTypeEnum, flushCache, useCache, resultOrdered,
        keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
  }

在解析完mapper文件里面的方法之后,最后会放到configuration的mappedStatements里面去
MyBatis入门源码一:配置解析_第16张图片

你可能感兴趣的:(mybatis,java,spring)