Introduction to mybatis Series II - configuration (mybatis source Chapter)

Note: reproduced from Nan Ke Meng

In the previous article, "getting started with Mybatis series (I) - Introduction to Mybatis", a Demo was written to simply reflect the process of Mybatis. This time, I will briefly introduce the configuration file of Mybatis:

In the last example, we used SqlSessionFactoryBuilder to create SqlSessionFactory. Then, let's start with SqlSessionFactoryBuilder and see how the source code is implemented

SqlSessionFactoryBuilder source code

public class SqlSessionFactoryBuilder {

  /**
  * Reader Read the mybatis configuration file and pass in the construction method
  * In addition to the Reader, there is also a corresponding inputStream as the construction method of parameters,
  * This also reflects the flexibility of mybatis configuration
  */
  public SqlSessionFactory build(Reader reader) {
    return build(reader, null, null);
  }

  public SqlSessionFactory build(Reader reader, String environment) {
    return build(reader, environment, null);
  }
  
  //Mybatis configuration file + properties. At this time, properties can be used in the mybatis configuration file in the form of ${}
  public SqlSessionFactory build(Reader reader, Properties properties) {
    return build(reader, null, properties);
  }
  
  //Parse mybatis configuration through XMLConfigBuilder and create SqlSessionFactory object
  public SqlSessionFactory build(Reader reader
        , String environment
        , Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
      //Let's take a look at the source code of this method
      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.
      }
    }
  }

  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

}

Through the source code, we can see that SqlSessionFactoryBuilder uses XMLConfigBuilder to parse the configuration file of mybatis that we passed in. Next, let's look at some source codes of XMLConfigBuilder:

Source code of XMLConfigBuilder

/**
 * mybatis Profile resolution
 */
public class XMLConfigBuilder extends BaseBuilder {
  public XMLConfigBuilder(InputStream inputStream,String environment,Properties props){
    this(new XPathParser(inputStream, true, props
            , new XMLMapperEntityResolver()), environment, props);
  }

  private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    super(new Configuration());
    ErrorContext.instance().resource("SQL Mapper Configuration");
    this.configuration.setVariables(props);
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
  }
  
  //Call this method externally to parse the mybatis configuration file
  public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    //From root configuration
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

  //This method is to resolve the child nodes under the configuration node
  //From this, we can see that the following 10 nodes can be configured under configuration
  private void parseConfiguration(XNode root) {
    try {
    //issue #117 read properties first
      propertiesElement(root.evalNode("properties")); 
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      settingsElement(root.evalNode("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);
    }
  }
}

From the above source code, we can see that in the configuration file of mybatis:

  1. The configuration node is the root node.

  2. Under the configuration node, we can configure 10 sub nodes: properties, typeAliases, plugins, objectFactory, objectWrapperFactory, settings, environments, databaseIdProvider, typeHandlers, and mappers.

This article only introduces these contents first, and the next article will analyze and analyze the source code of several important nodes in the 10 nodes in turn, to see what has been done when parsing these nodes.

Tags: Python Mybatis SQL

Posted on Tue, 05 Nov 2019 10:01:44 -0500 by PhillNeedsHelp