mybatis源码分析

4 篇文章 0 订阅
2 篇文章 0 订阅

mybatis源码分析(一)

mybatis 解析configuration中的properties

<configuration>

	<properties>
		<property name="username" value="root"/>
		<property name="password" value="123456"/>
	</properties>
</configuration>
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) 
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());  

1.创建一个新的Configuration对象

 private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    super(new Configuration());//创建新的Configuration对象
    ErrorContext.instance().resource("SQL Mapper Configuration");
    this.configuration.setVariables(props);**//这个是外部传入的属性**
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
  }
 public Configuration parse() {
    if (parsed) {  //已经解析过就直接抛出异常
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

2.parseConfiguration(parser.evalNode("/configuration")); 方法
parser.evalNode("/configuration") 这个是xnode解析节点
重点看parseConfiguration 这个

private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));  **//今天重点分析这段代码**
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      loadCustomVfs(settings);
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      settingsElement(settings);
      // read it after objectFactory and objectWrapperFactory issue #631
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }
  1. private void propertiesElement(XNode context) throws Exception {
private void propertiesElement(XNode context) throws Exception {
    if (context != null) {
      Properties defaults = context.getChildrenAsProperties();//先读取属性文件的
      String resource = context.getStringAttribute("resource");
      String url = context.getStringAttribute("url");
      if (resource != null && url != null) {    //resource 和url不能同时指定 否则抛出异常
        throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference.  Please specify one or the other.");
      }
      if (resource != null) {
        defaults.putAll(Resources.getResourceAsProperties(resource));
      } else if (url != null) {
        defaults.putAll(Resources.getUrlAsProperties(url));
      }
     //通过url或resource传进去的会把配置文件定义的覆盖掉
      Properties vars = configuration.getVariables();
      if (vars != null) {
        defaults.putAll(vars);
      }
      //通过SqlSessionFactory的build方法传入的会把前面的两种都覆盖掉
      parser.setVariables(defaults);
      configuration.setVariables(defaults);
    }
  }

4.总结
1.properties 标签resource和url只能有一个
2.properties优先级从低到高 标签里定义的->通过resource或url定义的->通过SqlSessionFactory的build方法传入的

扩展
从 MyBatis 3.4.2 开始,你可以为占位符指定一个默认值(这个用的很少)

<dataSource type="POOLED">
  <!-- ... -->
  <property name="username" value="${username:ut_user}"/> <!-- 如果属性 'username' 没有被配置,'username' 属性的值将为 'ut_user' -->
</dataSource>
<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <property name="org.apache.ibatis.parsing.PropertyParser.default-value-separator" value="?:"/> <!-- 修改默认值的分隔符 -->
</properties>

这个在之后的文章里再行解释

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值