实际上是调用了 DOM 中的 Node 类的 getChildNodes 函数, 并将返回的节点转换为 XNode , 添加到对应的 List 中返回。
3.2.3 获取子节点并存到 Properties 对象中 public Properties getChildrenAsProperties() { Properties properties = new Properties(); for (XNode child : getChildren()) { String name = child.getStringAttribute("name"); String value = child.getStringAttribute("value"); if (name != null && value != null) { properties.setProperty(name, value); } } return properties; }这些子节点都含有 name 和 value 属性, 存 name->value 的形式。
3.3 节点相关成员变量及其解析Configuration中有很多成员变量:
可以分为以下几种, 按配置的顺序:
3.3.1 properties 属性相关 3.3.1.1 成员变量 protected Properties variables = new Properties();对应 Properties>类, 可以将相应的配置 .properties 的文件信息存放到里面。
3.3.1.2 对应 XML 节点:<properties> <properties resource="mysql.properties"> </properties> 3.3.1.3 作用如 mysql.properties 文件, 其内容如下:
mysql.driver=com.mysql.jdbc.Driver mysql.url=jdbc:mysql://localhost:3306/mybatis mysql.username=root mysql.password=jim666在解析后, 存放在 variables 成员变量中, 是这样:
这样做的目的是我们可以将这些属性在后面的内容中复用:
<dataSource type="POOLED"> <property value="${mysql.driver}"/> <property value="${mysql.url}"/> <property value="${mysql.username}"/> <property value="${mysql.password}"/> </dataSource> 3.3.1.4 解析过程 private void propertiesElement(XNode context) throws Exception { if (context != null) { // 先解析<properties>下的各个子节点, 以name->value的形式记录到 Properties 对象中 Properties defaults = context.getChildrenAsProperties(); // 解析 resource 和 url 属性 String resource = context.getStringAttribute("resource"); String url = context.getStringAttribute("url"); // resource 和 url 属性不能同时不为空, 也就是说只能存在一个 if (resource != null && url != null) { throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference. Please specify one or the other."); } // 根据 resource 或 url, 将对应的 .properties 文件加载进来, 并将内容全部存到 Properties 对象中 if (resource != null) { defaults.putAll(Resources.getResourceAsProperties(resource)); } else if (url != null) { defaults.putAll(Resources.getUrlAsProperties(url)); } // 将Configuration 对象中原先的属性合并进来。 Properties vars = configuration.getVariables(); if (vars != null) { defaults.putAll(vars); } // 两个含有该成员变量的类对象更新 parser.setVariables(defaults); configuration.setVariables(defaults); } }几个要点:
先读取的是 <properties> 下的 <propertie> 属性;
<properties> 中, 不能同时存在 resource 和 url 属性;
更新时, 不单单只是更新 configuration, XPathParser 对象也需要更新, 后面用得到。
3.3.2 settings 属性相关 3.3.2.1 成员变量 protected boolean safeRowBoundsEnabled; protected boolean safeResultHandlerEnabled = true; protected boolean mapUnderscoreToCamelCase; protected boolean aggressiveLazyLoading; protected boolean multipleResultSetsEnabled = true; protected boolean useGeneratedKeys; protected boolean useColumnLabel = true; protected boolean cacheEnabled = true; protected boolean callSettersOnNulls; protected boolean useActualParamName = true; protected boolean returnInstanceForEmptyRow; protected String logPrefix; protected Class <? extends Log> logImpl; protected Class <? extends VFS> vfsImpl; protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION; protected JdbcType jdbcTypeForNull = JdbcType.OTHER; protected Set<String> lazyLoadTriggerMethods = new HashSet<String>(Arrays.asList(new String[] { "equals", "clone", "hashCode", "toString" })); protected Integer defaultStatementTimeout; protected Integer defaultFetchSize; protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE; protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL; protected AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior = AutoMappingUnknownColumnBehavior.NONE; protected boolean lazyLoadingEnabled = false; protected ProxyFactory proxyFactory = new JavassistProxyFactory(); protected Class<?> configurationFactory;