简单解析MyBatis配置文件

mybatis为什么这么写?

当我们在写mybatis配置文件的时候,可能会遇到这样的问题
The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".
这其实是mybatis在提示我们顺序配错了。那如果不用过idea的提示,我们应该怎么了解mybatis应该怎样去定义配置文件呢?

XMLConfigBuilder

在mybatis源码中能看到不少像XMLConfigBuilder这样的类,并且他们都继承了BaseBuilder,他的作用是负责解析mybatis-config.xml配置文件的。

源码分析

public class XMLConfigBuilder extends BaseBuilder {
    
    

  private boolean parsed;	// 判断是否已经解析过mybatis-config.xml文件

  // 用于解析配置文件的对象,这是由mybatis自己封装的一个对象,其底层还是使用了XPath(可以参考我上一篇文章)
  private final XPathParser parser;
 
  // 标识了<environment>(配置不同生产环境的不同配置)配置的名称,
  private String environment;

  // 负责创建和缓存Reflector对象(每一个对象都对应了一个类,以后会写文章仔细讲)
  private final ReflectorFactory localReflectorFactory = new DefaultReflectorFactory();

  // 省略各种构造函数
  public XMLConfigBuilder() {
    
    
  }
  
  // 解析mybatis-config.xml配置文件的入口
  public Configuration parse() {
    
    
    if (parsed) {
    
    	// 判断是否已经解析过
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    parseConfiguration(parser.evalNode("/configuration")); // 解析<configuration>
    return configuration;
  }

  // 通过这里我们就可以清楚为什么mybatis-config.xml根据怎么进行配置,为什么引用外部配置文件
  private void parseConfiguration(XNode root) {
    
    
    try {
    
    
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      loadCustomVfs(settings);
      loadCustomLogImpl(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);
    }
  }

这里将解析每一个节点都封装成一个特定的方法。由于篇幅过大,以后会将每一个方法写成一篇文章方便查看。

猜你喜欢

转载自blog.csdn.net/weixin_46357454/article/details/105958211