mybatis中的入口怎么看了?系统配置文件怎么加载的?

SqlSessionFactoryBuilder中的build方法是入口
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
  try {
    //解析为dom文件,用于进一步解析
    XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
    return build(parser.parse());
  } catch (Exception e) {
    throw ExceptionFactory.wrapException("Error building SqlSession.", e);
  } finally {
    ErrorContext.instance().reset();
    try {
      reader.close();
    } catch (IOException e) {
      // Intentionally ignore. Prefer previous error.
    }
  }
}
/**
 * 解析XML配置文件
 * @return
 */
public Configuration parse() {
  if (parsed) {
    throw new BuilderException("Each XMLConfigBuilder can only be used once.");
  }
  parsed = true;
  // parser.evalNode("/configuration"):通过XPATH解析器,解析configuration根节点
  // 从configuration根节点开始解析,最终将解析出的内容封装到Configuration对象中
  parseConfiguration(parser.evalNode("/configuration"));
  return configuration;
}

把配置中configuration进行解析:

private void parseConfiguration(XNode root) {
  try {
    //issue #117 read properties first
    // 解析</properties>标签
    propertiesElement(root.evalNode("properties"));
    // 解析</settings>标签
    Properties settings = settingsAsProperties(root.evalNode("settings"));
    loadCustomVfs(settings);
    loadCustomLogImpl(settings);
    // 解析</typeAliases>标签
    typeAliasesElement(root.evalNode("typeAliases"));
    // 解析</plugins>标签
    pluginElement(root.evalNode("plugins"));
    // 解析</objectFactory>标签
    objectFactoryElement(root.evalNode("objectFactory"));
    // 解析</objectWrapperFactory>标签
    objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
    // 解析</reflectorFactory>标签
    reflectorFactoryElement(root.evalNode("reflectorFactory"));
    settingsElement(settings);
    
    // read it after objectFactory and objectWrapperFactory issue #631
    // 解析</environments>标签
    environmentsElement(root.evalNode("environments"));
    // 解析</databaseIdProvider>标签
    databaseIdProviderElement(root.evalNode("databaseIdProvider"));
    // 解析</typeHandlers>标签
    typeHandlerElement(root.evalNode("typeHandlers"));
    // 解析</mappers>标签
    mapperElement(root.evalNode("mappers"));
  } catch (Exception e) {
    throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
  }
}

解析标签说明:

properties属性是用来引入外部properties配置文件的内容

settings是mybatis中的一些设置,比如一级二级缓存等。
private void settingsElement(Properties props) {
  configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL")));
  configuration.setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.valueOf(props.getProperty("autoMappingUnknownColumnBehavior", "NONE")));
  configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true));
  configuration.setProxyFactory((ProxyFactory) createInstance(props.getProperty("proxyFactory")));
  configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false));
  configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), false));
  configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true));
  configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true));
  configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false));
  configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
  configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null));
  configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null));
  configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false));
  configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false));
  configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION")));
  configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER")));
  configuration.setLazyLoadTriggerMethods(stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString"));
  configuration.setSafeResultHandlerEnabled(booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true));
  configuration.setDefaultScriptingLanguage(resolveClass(props.getProperty("defaultScriptingLanguage")));
  configuration.setDefaultEnumTypeHandler(resolveClass(props.getProperty("defaultEnumTypeHandler")));
  configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false));
  configuration.setUseActualParamName(booleanValueOf(props.getProperty("useActualParamName"), true));
  configuration.setReturnInstanceForEmptyRow(booleanValueOf(props.getProperty("returnInstanceForEmptyRow"), false));
  configuration.setLogPrefix(props.getProperty("logPrefix"));
  configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory")));
}
typeAliases 是别名定义,如果直接配置的包,则进行反射拿到对应的类小写。
plugins 是指插件配置,比如需要进行拦截查询的,在查询前面进行输出sql语句。需要配置plugins。
objectFactory 是针对于反射的,当需要同意赋值当时候可以用的上。

ObjectWrapperFactory 指定的对象进行特殊的加工

reflectorFactory 是反射工具包
environments 配置一些环境变变量,可以配置多个数据源。
databaseIdProvider 定义多数据源支持

<!-- 定义多数据库支持-->
    <databaseIdProvider type="DB_VENDOR">
        <property name="MySQL" value="mysql"/> <!--mysql的定义 -->
        <property name="Oracle" value="oracle"/><!--oracle的定义 -->
        <property name="SQL Server" value="sqlserver"/>
    </databaseIdProvider>

typeHandlers 是类处理器,进行转换类型的。
mappers 是xml 的配置。

其中

mappers 会进行其他的解析:
/**
 * 解析<mappers>标签
 * @param parent  mappers标签对应的XNode对象
 * @throws Exception
 */
private void mapperElement(XNode parent) throws Exception {
  if (parent != null) {
    // 获取<mappers>标签的子标签
    for (XNode child : parent.getChildren()) {
   // <package>子标签
      if ("package".equals(child.getName())) {
        // 获取mapper接口和mapper映射文件对应的package包名
        String mapperPackage = child.getStringAttribute("name");
        // 将包下所有的mapper接口以及它的代理对象存储到一个Map集合中,key为mapper接口类型,value为代理对象工厂
        configuration.addMappers(mapperPackage);
      } else {// <mapper>子标签
        // 获取<mapper>子标签的resource属性
        String resource = child.getStringAttribute("resource");
        // 获取<mapper>子标签的url属性
        String url = child.getStringAttribute("url");
        // 获取<mapper>子标签的class属性
        String mapperClass = child.getStringAttribute("class");
        // 它们是互斥的
        if (resource != null && url == null && mapperClass == null) {
          ErrorContext.instance().resource(resource);
          InputStream inputStream = Resources.getResourceAsStream(resource);
          // 专门用来解析mapper映射文件
          XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
          // 通过XMLMapperBuilder解析mapper映射文件
          mapperParser.parse();
        } else if (resource == null && url != null && mapperClass == null) {
          ErrorContext.instance().resource(url);
          InputStream inputStream = Resources.getUrlAsStream(url);
          XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
          // 通过XMLMapperBuilder解析mapper映射文件
          mapperParser.parse();
        } else if (resource == null && url == null && mapperClass != null) {
          Class<?> mapperInterface = Resources.classForName(mapperClass);
          // 将指定mapper接口以及它的代理对象存储到一个Map集合中,key为mapper接口类型,value为代理对象工厂
          configuration.addMapper(mapperInterface);
        } else {
          throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
        }
      }
    }
  }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值