Mybatis source code – configuration loading

Time:2021-11-25

preface

In the originalMybatisIn useMybatisThe configuration file will be read firstmybatis-config.xmlFor character stream or byte stream, and then throughSqlSessionFactoryBuilderBuild based on the character stream or byte stream of the configuration fileSqlSessionFactory。 This section will combineMybatisSource code, read the configuration filemybatis-config.xmlAnd buildSqlSessionFactoryLearn the principle of.

text

originalMybatisRead configuration filemybatis-config.xmlAnd buildSqlSessionFactoryAn example of is as follows.

InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

In the example aboveResourcesTool classes provide methods that can be readclasspathThe file with the specified name is a character stream or a byte stream, which is used heregetResourceAsStream()Method willmybatis-config.xmlThe file is read as a byte stream.SqlSessionFactoryBuilderIs a builder that provides a total of 9 overloadedbuild()Method for buildingSqlSessionFactory, these ninebuild()Methods can be divided into three categories, which are summarized as follows.

  • Character stream construction based on configuration fileSqlSessionFactory
  • Byte stream construction based on configuration fileSqlSessionFactory
  • be based onConfigurationClass constructionSqlSessionFactory

In fact, both the character stream based on the configuration file and the byte stream based on the configuration file are finally parsed and generatedConfigurationClass, and then based onConfigurationClass constructionSqlSessionFactory

The following is built based on the configuration file byte streamSqlSessionFactoryAs an example, the whole process of reading configuration files is described. Invoked in the above examplebuild()The method is as follows.

public SqlSessionFactory build(InputStream inputStream) {
    return build(inputStream, null, null);
}

Overloaded called abovebuild()The method is as follows.

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
        //Xmlconfigbuilder parses the configuration file and generates the configuration class
        XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
        //Call the build () method whose input parameter is configuration to build sqlsessionfactory and return
        return build(parser.parse());
    } catch (Exception e) {
        throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
        ErrorContext.instance().reset();
        try {
            inputStream.close();
        } catch (IOException e) {

        }
    }
}

It can be found that the resolution of the configuration file occurs inXMLConfigBuilderofparse()Method, in viewparse()Take a look before using the methodXMLConfigBuilderClass diagram, as shown below.

Mybatis source code - configuration loading

adoptXMLConfigBuilderAs you can see from the class diagram,XMLConfigBuilderParsing configuration files depends onXPathParser, andXPathParseryesMybatisProvided based onJAVA XPathParser for. At the same time,XMLConfigBuilderInternally maintained aConfiguration, passXPathParserThe configuration properties obtained by parsing the configuration file will be enriched toConfigurationYes.

Now start the analysisXMLConfigBuilderofparse()The method is implemented as follows.

public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
}

To understandparse()Method, it is best to compare with an actual configuration file. An actual configuration file is given below.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="useGeneratedKeys" value="true"/>
    </settings>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&amp;serverTimezone=UTC&amp;useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <package name="com.mybatis.learn.dao"/>
    </mappers>
</configuration>

So inparse()Method, the first is to obtain the configuration fileconfigurationNode (root node), and thenconfigurationNode incomingparseConfiguration()Method, and thenparseConfiguration()Method based on the passed inconfigurationThe node obtains the child nodes in turn and reads the child node attributes, and finally enriches the obtained attributesConfigurationparseConfiguration()The method is implemented as follows.

private void parseConfiguration(XNode root) {
    try {
        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);
        //Enrich the properties of the environments tag and its sub tags into the configuration
        environmentsElement(root.evalNode("environments"));
        databaseIdProviderElement(root.evalNode("databaseIdProvider"));
        typeHandlerElement(root.evalNode("typeHandlers"));
        //Enrich the properties of the mappers tag into the configuration
        mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
        throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
}

lastparse()Method returnsConfigurationSqlSessionFactoryBuilderWill be based onConfigurationestablishDefaultSqlSessionFactoryAnd return, as shown below.

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

DefaultSqlSessionFactoryThe class diagram is shown below.

Mybatis source code - configuration loading

At this point, read the configuration filemybatis-config.xmlAnd buildSqlSessionFactoryThe basic principle of has been introduced.

summary

This article is rightMybatisRead configuration file and buildSqlSessionFactoryAn overall process is introduced, that is, throughResourcesThe tool class obtains the input character stream or byte stream of the configuration file, and thenSqlSessionFactoryBuilderestablishDefaultSqlSessionFactory, inSqlSessionFactoryBuilderIs throughXMLConfigBuilderTo read and enrich the properties of the configuration fileConfigurationSqlSessionFactoryBuilderAlso based onXMLConfigBuilderReturnedConfigurationCreatedDefaultSqlSessionFactory。 In fact, aboutMybatisThe key to reading configuration files is how to registerMapping file / mapping interface, this part will be studied in the following articles.

Recommended Today

Apache sqoop

Source: dark horse big data 1.png From the standpoint of Apache, data flow can be divided into data import and export: Import: data import. RDBMS—–>Hadoop Export: data export. Hadoop—->RDBMS 1.2 sqoop installation The prerequisite for installing sqoop is that you already have a Java and Hadoop environment. Latest stable version: 1.4.6 Download the sqoop installation […]