• 周六. 10 月 12th, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

Getting started with mybatis to source code analysis

King Wang

1 月 3, 2022

List of articles

  • Mybatis Introductory cases
    • establish maven engineering , Introduce dependency configuration items
    • database
    • javabean
    • jdbc.properties
    • mybatis Core profile
    • mapper.xml The mapping file
    • Mapper.java Interface
    • Test class
  • Mybatis Load core profile process
    • 1. entrance
    • 2. Create a 【XMLConfigBuilder】 Parser class
    • 3.【XPathParser】 The constructor of the parser
    • 4.【XMLMapperEntityResolver】 Entity Resolver
    • 5. Go back to 【3】 Step by step : structure XPathParser
    • 6. Go back to 【2】 Step by step ,81 Row or so :
      • 6.1. first line `super(new Configuration());`
      • 6.2. **Configuration** Class is Mybatis The core configuration class , It’s so important !
    • 7. Go back to the first step SqlSessionFactoryBuilder#build
      • 7.1 see `org.apache.ibatis.session.SqlSessionFactoryBuilder#build(org.apache.ibatis.session.Configuration)` Method
      • 7.2 `parser.parse()` Method
      • 7.3 And then execute this method XMLConfigBuilder#parseConfiguration

Mybatis Introductory cases

establish maven engineering , Introduce dependency configuration items

pom.xml Introduction in maven rely on :

<dependencies>
<!--MyBatis coordinate -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql drive -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- unit testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>

database

CREATE DATABASE mybatis;
USE mybatis;
CREATE TABLE `t_user` (
`uid` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(40) DEFAULT NULL,
`sex` VARCHAR(10) DEFAULT NULL,
`birthday` DATE DEFAULT NULL,
`address` VARCHAR(40) DEFAULT NULL,
`level` VARCHAR(10) DEFAULT NULL,
PRIMARY KEY (`uid`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
insert into `t_user`(`uid`,`username`,`sex`,`birthday`,`address`,`level`) values (1,'zs',' male ','2018-08-08',' Beijing ','LOW'),(2,'ls',' Woman ','2018-08-30',' wuhan ','MIDDLE'),(3,'ww',' male ','2018-08-08',' Beijing ','LOW');

javabean

User.java class

public class User implements Serializable {

private int uid; // user id
private String username;// User name 
private String sex;// Gender 
private Date birthday;// Birthday 
private String address;// Address 
// get、set...
}

jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis
username=root
password=root

mybatis Core profile

resources Create under directory :mybatis-config.xml, And write the following :

<?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>
<!-- Import external profile -->
<properties resource="jdbc.properties" />
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="useActualParamName" value="true"/>
<setting name="logImpl" value="SLF4J"/>
<!-- Self defined VFS -->
<setting name="vfsImpl" value="org.byron4j.vfs.MyVFS"/>
</settings>
<!-- Alias mode 1 : Single -->
<typeAliases>
<typeAlias alias="user2" type="org.byron4j.bean.User"/>
<typeAlias alias="int" type="java.lang.Integer"/>
<!-- Mode two , All classes in this package are named by default , And case insensitive
Such as : org.byron4j.bean.Product Another name will be product、Product、ProDuCt Fine
-->
<package name="org.byron4j.bean"/>
</typeAliases>
<typeHandlers>
<!-- Mode one : Single processor -->
<!--<typeHandler handler="org.byron4j.handler.MyHandler" javaType="org.byron4j.bean.User"/>-->
<typeHandler handler="org.byron4j.handler.MyDateHandler" javaType="long" jdbcType="TIMESTAMP"/>
<!-- Unified automatic search -->
<package name="org.byron4j.handler"/>
</typeHandlers>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--<databaseIdProvider type="DB_VENDOR" />-->
<mappers>
<mapper resource="org/byron4j/mapper/UserMapper.xml"/>
</mappers>
</configuration>

mapper.xml The mapping file

resources Create a directory under directory org/byron4j/mapper Catalog ( Note that the directory needs to be consistent with the package level of the interface ), Create a new one UserMapper.xml, Write the following :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace: The name space , Fully qualified name of the interface -->
<mapper namespace="org.byron4j.mapper.UserMapper">
<!--
id attribute : Same as the method name of the interface
resultType attribute : Return type , Write full name , Set writes the generic type of the element
Tagging body :sql sentence
-->
<!-- The alias is used here User01 Case insensitive ; When there is only one parameter, you can write the parameter name as you like here aaa, But in the actual development, it is recommended to keep consistent with the parameter name -->
<select id="findById" resultType="User01">
select * from t_user where uid = #{aaa}
</select>
</mapper>

Mapper.java Interface

package org.byron4j.mapper Create an interface :UserMapper.java

public interface UserDao {

User findById(Integer id);
}

Test class

Write a test class :

@Test
public void test() throws Exception {

// 1. Read configuration file as stream 
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 2. Get... From the core configuration file SqlSessionFactory object 
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
// 3. obtain SqlSession object ( similar connection)
SqlSession sqlSession = build.openSession();
// 4. Get proxy object 
UserDao mapper = sqlSession.getMapper(UserDao.class);
// 5. operation , Release resources 
User user = mapper.findById(2);
System.out.println(user);
sqlSession.close();
is.close();
}

This is a simple introduction case , After using it . We can come to learn Mybatis Loading the core configuration file process .

Mybatis Load core profile process

1. entrance

org.apache.ibatis.session.SqlSessionFactoryBuilder#build(java.io.InputStream, java.lang.String)
The first parameter of this method is a mybatis The input stream represented by the configuration file ; The second parameter is the environment , Here we default to .

It calls the following methods :
org.apache.ibatis.session.SqlSessionFactoryBuilder#build(java.io.InputStream, java.lang.String, java.util.Properties).

In our case, only the first parameter has a value , The back are all null.

Let’s start tracking the source code

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {

try {

// Create a 【XMLConfigBuilder】 Parser class 
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
} catch (Exception e) {

throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {

ErrorContext.instance().reset();
try {

inputStream.close();
} catch (IOException e) {

// Intentionally ignore. Prefer previous error.
}
}
}

2. Create a 【XMLConfigBuilder】 Parser class

Continue tracking org.apache.ibatis.builder.xml.XMLConfigBuilder#XMLConfigBuilder( The core configuration xml file , Environmental Science env, Don't specify properties Then for null) Method :

public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {

this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()),
environment, props);
}

The method body calls the overloaded constructor :org.apache.ibatis.builder.xml.XMLConfigBuilder#XMLConfigBuilder(org.apache.ibatis.parsing.XPathParser, java.lang.String, java.util.Properties)
The first parameter here is a XPathParser Type of parser ( Look at the name. It’s XPath The parser ).

It’s used here XPathParser Constructors , So let’s see .

3.【XPathParser】 The constructor of the parser

Constructors :org.apache.ibatis.parsing.XPathParser#XPathParser(java.io.InputStream, true, java.util.Properties by null, org.xml.sax.EntityResolver)
The fourth parameter is an entity parser :org.apache.ibatis.builder.xml.XMLMapperEntityResolver, Realized org.xml.sax.EntityResolver Interface ;

So we need to check XMLMapperEntityResolver What kind of thing is this .

4.【XMLMapperEntityResolver】 Entity Resolver

org.apache.ibatis.builder.xml.XMLMapperEntityResolver, Realized org.xml.sax.EntityResolver Interface ; After implementing this interface , Can be used to customize interception resolution XML, Like using mybatis The definition of constraints can be conditional judgment to do some other logic .
Here is a simple example , Just make a statement :

public class MyResolver implements EntityResolver {

public InputSource resolveEntity (String publicId, String systemId)
{

if (systemId.equals("http://www.myhost.com/today")) {

// Includes custom , Then resolve and process by yourself 
MyReader reader = new MyReader();
return new InputSource(reader);
} else {

// use the default behaviour
return null;
}
}
}

XMLMapperEntityResolver This parser is to judge systemId(xml The document declaration of ) contain org/apache/ibatis/builder/xml/mybatis-3-config.dtd Just use mybatis Self defined InputSource(xml File configuration input source ):

private InputSource getInputSource(String path, String publicId, String systemId) {

InputSource source = null;
if (path != null) {

try {

// path yes mybatis-3-config.dtd The path of 
InputStream in = Resources.getResourceAsStream(path);
source = new InputSource(in);
source.setPublicId(publicId);
source.setSystemId(systemId);
} catch (IOException e) {

// ignore, null is ok
}
}
return source;
}

So you should be able to understand through XMLMapperEntityResolver Just got one InputSource object (SAX The parser will use this InputSource Object to determine how to read XML Input ).

5. Go back to 【3】 Step by step : structure XPathParser

XMLMapperEntityResolver After understanding , Let’s go back to XPathParser here , structure XPathParserorg.apache.ibatis.parsing.XPathParser#XPathParser(java.io.InputStream, boolean, java.util.Properties, org.xml.sax.EntityResolver)

Constructors :( stay XPathParser Class 123 Office )

// inputStream It's in our project mybatis Core profile , Such as :`D:\007\mybatis_demo01\target\classes\SqlMapperConfig.xml`
public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {

// This constructor initializes an internal property :javax.xml.xpath.XPath
commonConstructor(validation, variables, entityResolver);
// Initialize internal properties :org.w3c.dom.Document, Get one dom file 
this.document = createDocument(new InputSource(inputStream));
}

6. Go back to 【2】 Step by step ,81 Row or so :

XPathParser When we understand the structure of , Go back to 【2】 Step , to glance at XMLConfigBuilder The construction logic of

Code location XMLConfigBuilder:org.apache.ibatis.builder.xml.XMLConfigBuilder#XMLConfigBuilder(org.apache.ibatis.parsing.XPathParser, java.lang.String, java.util.Properties)
Actually called 85 Lines of code around the method :org.apache.ibatis.builder.xml.XMLConfigBuilder#XMLConfigBuilder(org.apache.ibatis.parsing.XPathParser, java.lang.String, java.util.Properties)
The method is as follows , Here’s a look at the first line of code Configuration The creation of :

private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {

super(new Configuration());
ErrorContext.instance().resource("SQL Mapper Configuration");
// Set some properties 
this.configuration.setVariables(props);
this.parsed = false;
this.environment = environment;
this.parser = parser;
}

Let’s take a closer look at the logic of this method .

6.1. first line super(new Configuration());

The first line calls the constructor of the parent class , namely :org.apache.ibatis.builder.BaseBuilder#BaseBuilder

public BaseBuilder(Configuration configuration) {

this.configuration = configuration;
this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
}

6.2. Configuration Class is Mybatis The core configuration class , It’s so important !

Let’s take a look at the direct new The nonparametric constructor of the configuration information class : new Configuration():

public Configuration() {

typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);
typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
typeAliasRegistry.registerAlias("LRU", LruCache.class);
typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
typeAliasRegistry.registerAlias("WEAK", WeakCache.class);
typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);
typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);
typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);
typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);
languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
languageRegistry.register(RawLanguageDriver.class);
}

What’s in it corresponds to what we are in mybatis Core profile (mybatis-config.xml) The property value configured in corresponds to the specific java Class mapping .

Configuration Class also defines a lot of properties , This is mainly about the analysis of loading process , Don’t expand on these properties , Just list a few instructions in the code comments below :

public class Configuration {

// Environment configuration :<environment id="dev">
protected Environment environment;
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;
// Prefix settings when outputting logs 
protected String logPrefix;
// Specify the log implementation class ; Otherwise, it defaults to the order :SLF4J、Apache Commons Logging、Log4j 2、Log4j、JDK logging Find the implementation ;
protected Class <? extends Log> logImpl;
// Virtual file system , Will read interface Mapper.class file 
protected Class <? extends VFS> vfsImpl;
// The default level 1 cache is session Level ( Another value is statement Level )
protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;
protected JdbcType jdbcTypeForNull = JdbcType.OTHER;
// When you call these methods , Late loaded objects are loaded before these methods are called 
protected Set<String> lazyLoadTriggerMethods = new HashSet<String>(Arrays.asList(new String[] {
 "equals", "clone", "hashCode", "toString" }));
protected Integer defaultStatementTimeout;
protected Integer defaultFetchSize;
// Default actuator type ,SIMPLE( Default ), REUSE, BATCH
protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
// Set up mapper.xml The columns of the table in (column) and javabean Properties of (properties) The behavior of automatic mapping 
protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL;
protected AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior = AutoMappingUnknownColumnBehavior.NONE;
protected Properties variables = new Properties();
protected ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
protected ObjectFactory objectFactory = new DefaultObjectFactory();
protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();
protected boolean lazyLoadingEnabled = false;
protected ProxyFactory proxyFactory = new JavassistProxyFactory(); // #224 Using internal Javassist instead of OGNL
protected String databaseId;
/**
* Configuration factory class.
* Used to create Configuration for loading deserialized unread properties.
*
* @see <a href='https://code.google.com/p/mybatis/issues/detail?id=300'>Issue 300 (google code)</a>
*/
protected Class<?> configurationFactory;
// Mapper registry : Using the proxy pattern ; By MapperProxy The agent creates the corresponding interface Mapper Instance 
protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
// The interceptor chain , Inside list attribute interceptors Encapsulates all interceptor objects (org.apache.ibatis.plugin.Interceptor)
protected final InterceptorChain interceptorChain = new InterceptorChain();
// Type processor registry 
protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
// Type alias registry 
protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
// Language driver registry ( These objects generally refer to org.apache.ibatis.scripting.LanguageDriver Subclasses of )
// mybatis Default org.apache.ibatis.scripting.xmltags.XMLLanguageDriver type 
protected final LanguageDriverRegistry languageRegistry = new LanguageDriverRegistry();
protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection");
protected final Map<String, Cache> caches = new StrictMap<Cache>("Caches collection");
protected final Map<String, ResultMap> resultMaps = new StrictMap<ResultMap>("Result Maps collection");
protected final Map<String, ParameterMap> parameterMaps = new StrictMap<ParameterMap>("Parameter Maps collection");
protected final Map<String, KeyGenerator> keyGenerators = new StrictMap<KeyGenerator>("Key Generators collection");
protected final Set<String> loadedResources = new HashSet<String>();
protected final Map<String, XNode> sqlFragments = new StrictMap<XNode>("XML fragments parsed from previous mappers");
protected final Collection<XMLStatementBuilder> incompleteStatements = new LinkedList<XMLStatementBuilder>();
protected final Collection<CacheRefResolver> incompleteCacheRefs = new LinkedList<CacheRefResolver>();
protected final Collection<ResultMapResolver> incompleteResultMaps = new LinkedList<ResultMapResolver>();
protected final Collection<MethodResolver> incompleteMethods = new LinkedList<MethodResolver>();
/*
* A map holds cache-ref relationship. The key is the namespace that
* references a cache bound to another namespace and the value is the
* namespace which the actual cache is bound to.
*/
protected final Map<String, String> cacheRefMap = new HashMap<String, String>();
}

7. Go back to the first step SqlSessionFactoryBuilder#build

So far , It has been constructed XMLConfigBuilder Object .

Let’s go back to the first step org.apache.ibatis.session.SqlSessionFactoryBuilder#build(java.io.InputStream, java.lang.String, java.util.Properties), That is to say SqlSessionFactoryBuilder Class 75 Row or so .

Configuration object public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {

try {

// parser It's got ;【 So far , It has been constructed XMLConfigBuilder Object .】
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
// Start tracking here ....[parser.parse() obtain Configuration object ]
return build(parser.parse());
} catch (Exception e) {

throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {

ErrorContext.instance().reset();
try {

inputStream.close();
} catch (IOException e) {

// Intentionally ignore. Prefer previous error.
}
}
}

7.1 see org.apache.ibatis.session.SqlSessionFactoryBuilder#build(org.apache.ibatis.session.Configuration) Method

build(parser.parse()) This line of code calls this method :

public SqlSessionFactory build(Configuration config) {

return new DefaultSqlSessionFactory(config);
}

This method introduces a Configuration Object as parameter , This parameter we know is through parser.parse() Got .
So pay attention to parser.parse().

7.2 parser.parse() Method

In fact, that is :org.apache.ibatis.builder.xml.XMLConfigBuilder#parse Method . stay XMLConfigBuilder Class 94 Row or so .

public Configuration parse() {

if (parsed) {
// mybatis The core configuration file can only be loaded once 
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
// It's using XPath Get root node : Namely config.xml The root node inside : `<configuration>`.
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}

parser.evalNode(“/configuration”) This line of code uses XPath Get root node : Namely config.xml The root node inside : <configuration>.

7.3 And then execute this method XMLConfigBuilder#parseConfiguration

Take a look at this line of code parseConfiguration(parser.evalNode("/configuration"));.

org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration, stay XMLConfigBuilder Class 103 Row or so .

This method is parsing read mybatis-config.xml Each configuration item of the file , And assign it to configuration Go inside ( The bottom is configuration.setXXX Method setting ):

private void parseConfiguration(XNode root) {

try {

//issue #117 read properties first
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(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);
}
}

Here we choose this line of code environmentsElement(root.evalNode("environments")); Just follow up :

org.apache.ibatis.builder.xml.XMLConfigBuilder#environmentsElement The method is as follows , You should be able to see some familiar words ( Configuration information of data source ):

private void environmentsElement(XNode context) throws Exception {

if (context != null) {

if (environment == null) {

environment = context.getStringAttribute("default");
}
for (XNode child : context.getChildren()) {

String id = child.getStringAttribute("id");
if (isSpecifiedEnvironment(id)) {

TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
DataSource dataSource = dsFactory.getDataSource();
Environment.Builder environmentBuilder = new Environment.Builder(id)
.transactionFactory(txFactory)
.dataSource(dataSource);
configuration.setEnvironment(environmentBuilder.build());
}
}
}
}

Is to get environments Node information :

<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>

This is it. MyBatis Core configuration object Configuration The main process of parsing and loading .

发表回复