如果我们使用 Spring 集成 Mybatis 使用的话,可以在 Spring 的配置文件,比如 applicationContext.xml
或者其他自定义的配置文件中找到下面这一段配置。
可以从上面了解到使用了 SqlSessionFactoryBean 作为 Spring 加载配置文件的主入口,并且将 dataSource 和 configLocation 两个属性值注入到 SqlSessionFactoryBean,并且等待 Spring 启动的时候将注册过的 SqlSessionFactoryBean 加载。当然这边并不准备细讲 SqlSessionFactoryBean,而是主要对 Mybatis 做详细了解。
在 SqlSessionFactoryBean 可以找到 xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
这一行代码,这行代码则是加载 mybatis-config.xml 真正的过程,也就是说 XMLConfigBuilder 是专门负责 mybatis-config.xml 加载的一个类。再往下找则可以找到 XMLConfigBuilder 对配置进行解析的部分,下面代码中 xmlConfigBuilder.parse();
则是 XMLConfigBuilder 真正开始解析的位置,并且可以在其中找到 parseConfiguration()
这一个方法。
if (xmlConfigBuilder != null) { try { xmlConfigBuilder.parse(); LOGGER.debug(() -> "Parsed configuration file: '" + this.configLocation + "'"); } catch (Exception ex) { throw new NestedIOException("Failed to parse config resource: " + this.configLocation, ex); } finally { ErrorContext.instance().reset(); }
}
XMLConfigBuilder 主要通过 XMLConfigBuilder#parseConfiguration()
实现配置文件的解析过程,如果有对 Mybatis 的配置文件详细解读过一遍,就可以知道,下面代码中就是将 xml 配置文件的各个节点进行解析一遍。为了方便查阅,下面贴出原始的 Mybatis 配置文件中可以选择的配置项,当然如果是 Spring 集成了 Mybatis,则可以在相对应的标签中找到下面的选项。
- configuration(根节点)- properties(属性)- settings(设置)- typeAliases(类型别名)- typeHandlers(类型处理器)- objectFactory(对象工厂)- plugins(插件)- environments(环境配置)- environment(子节点)- transactionManager(事务管理器)- dataSource(数据源)- databaseIdProvider(数据库厂商标识)- mappers(映射器)
private void parseConfiguration(XNode root) {try {// 解析 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);// 解析 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);}
}
节点其实就是对配置文件中需要重复使用的一些变量提取并且通过设置键值对的方式来让其他配置方便调取使用,而不需要再各个配置中重复配置使用,这样既方便了使用,也方便了修改。
因为
节点中有多个属性,有 resource 和 url,而且这两个属性还不能同时使用,同时使用的时候会报错。
使用方式参考链接:【Mybatis 使用】mybatis-config.xml 配置(properties 和 settings)
properties 使用方式和其他配置文件差不多,下面先是设置了 username 和 password 两个属性,然后在具体使用的时候,使用 ${key}
的方式来获取,当然如果在另一个地方有一个专门的属性配置文件,则可以在
节点中加 resource 属性,来将这些另外的属性加入到其中。
private void propertiesElement(XNode context) throws Exception {// 传入的 properties 节点if (context != null) {// 获取 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 属性,则会解析 resourceif (resource != null) {defaults.putAll(Resources.getResourceAsProperties(resource));} else if (url != null) {// 如果填写了 url 属性,则会解析 urldefaults.putAll(Resources.getUrlAsProperties(url));}// 获取 properties 中配置的键值对Properties vars = configuration.getVariables();if (vars != null) {defaults.putAll(vars);}// 将配置的属性放入到解析器和全局 configuration 中parser.setVariables(defaults);configuration.setVariables(defaults);}
}