mybaits源码-配置-默认配置

  作者:记性不好的阁主

中文文档:https://mybatis.org/mybatis-3/zh/getting-started.html


mybatis-config.xml


<?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>
<properties resource="config.properties">
<!-- 按需定义全局变量,以供整个配置文件使用-->
<!-- <property name="globalVariable" value="value"/>-->
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/PersonMapper.xml"/>
</mappers>
</configuration>


测试入口:


package com.laoxu.mybatis.executor;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class start {

public static void main(String[] args) throws IOException {
// user.dir指定了当前的路径
String userDir = System.getProperty("user.dir");
System.out.println(userDir);
// 获取类路径
String classPath = start.class.getResource("/").getPath();
System.out.println(classPath);
// 根据当前类路径下的相对路径 (classPath + {path})
String resource = "mapper/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}

}


构建SqlSessionFactory工厂:入参(输入流)


/**
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.session;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Properties;

import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.exceptions.ExceptionFactory;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;

/**
* Builds {@link SqlSession} instances.
*
* @author Clinton Begin
*/
public class SqlSessionFactoryBuilder {

// 构造1
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}

// 构造2
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
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.
}
}
}

// 构造3
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}

}


SqlSessionFactoryBuilder 构造2:


构造xml配置


XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);


/**
* Copyright 2009-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.builder.xml;

import java.io.InputStream;
import java.io.Reader;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.builder.BaseBuilder;
import org.apache.ibatis.builder.BuilderException;
import org.apache.ibatis.datasource.DataSourceFactory;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.executor.loader.ProxyFactory;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.io.VFS;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.parsing.XPathParser;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaClass;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.AutoMappingBehavior;
import org.apache.ibatis.session.AutoMappingUnknownColumnBehavior;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.LocalCacheScope;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.type.JdbcType;

/**
* @author Clinton Begin
* @author Kazuki Shimizu
*/
public class XMLConfigBuilder extends BaseBuilder {

private boolean parsed;
private final XPathParser parser;
private String environment;

// 构造1
public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
}
// 构造2
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;
}



}


  • XMLConfigBuilder 需要构造的实体类:


new XMLMapperEntityResolver()


new XPathParser(inputStream, true, props, new XMLMapperEntityResolver())


new Configuration()



解析开始:


1、实例化一个XML映射实体解析器


/**
* Copyright 2009-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.builder.xml;

import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;

import org.apache.ibatis.io.Resources;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* MyBatis dtd的离线实体解析器。
*
* @author Clinton Begin
* @author Eduardo Macarron
*/
public class XMLMapperEntityResolver implements EntityResolver {

private static final String IBATIS_CONFIG_SYSTEM = "ibatis-3-config.dtd";
private static final String IBATIS_MAPPER_SYSTEM = "ibatis-3-mapper.dtd";
private static final String MYBATIS_CONFIG_SYSTEM = "mybatis-3-config.dtd";
private static final String MYBATIS_MAPPER_SYSTEM = "mybatis-3-mapper.dtd";

private static final String MYBATIS_CONFIG_DTD = "org/apache/ibatis/builder/xml/mybatis-3-config.dtd";
private static final String MYBATIS_MAPPER_DTD = "org/apache/ibatis/builder/xml/mybatis-3-mapper.dtd";

/**
* 将公共DTD转换为本地DTD
*
* @param publicId
* 公共id,在" public "后面
* @param systemId
* 在公共id之后的系统id
* @return DTDInputSource
*
* @throws org.xml.sax.SAXException
* 如果出了什么差错
*/
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException {
// 去读取mybatis-config.xml头标签<!DOCTYPE configuration ...param>的两个参数
try {
if (systemId != null) {
// 系统id小写处理
String lowerCaseSystemId = systemId.toLowerCase(Locale.ENGLISH);
if (lowerCaseSystemId.contains(MYBATIS_CONFIG_SYSTEM) ||
lowerCaseSystemId.contains(IBATIS_CONFIG_SYSTEM)) {
// 如果系统id包含 系统配置 标识
return getInputSource(MYBATIS_CONFIG_DTD, publicId, systemId);
} else if (lowerCaseSystemId.contains(MYBATIS_MAPPER_SYSTEM) ||
lowerCaseSystemId.contains(IBATIS_MAPPER_SYSTEM)) {
// 如果系统id包含 映射系统 标识
return getInputSource(MYBATIS_MAPPER_DTD, publicId, systemId);
}
}
return null;
} catch (Exception e) {
throw new SAXException(e.toString());
}
}

/**
* 获取输入源
* @param path 路径
* @param publicId 公共id
* @param systemId 系统Id
* @return
*/
private InputSource getInputSource(String path, String publicId, String systemId) {
InputSource source = null;
if (path != null) {
try {
// 去类路径获取输入流
InputStream in = Resources.getResourceAsStream(path);
source = new InputSource(in);
source.setPublicId(publicId);
source.setSystemId(systemId);
} catch (IOException e) {
// 忽略,null也可以
}
}
return source;
}

}


2、实例化XPathParser解析器


/**
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.parsing;

import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.apache.ibatis.builder.BuilderException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
* @author Clinton Begin
* @author Kazuki Shimizu
*/
public class XPathParser {

private final Document document;
private boolean validation;
private EntityResolver entityResolver;
private Properties variables;
private XPath xpath;

public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {
commonConstructor(validation, variables, entityResolver);
this.document = createDocument(new InputSource(inputStream));
}

private Document createDocument(InputSource inputSource) {
// 重要提示:这个函数只能在通用构造函数之后调用
try {
//创建DocumentBuilderFactory实例对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
/**
* 设置是否启用DTD验证
*/
factory.setValidating(validation);
/**
* 设置是否支持XML名称空间
*/
factory.setNamespaceAware(false);
/**
* 设置解析器是否忽略注释
*/
factory.setIgnoringComments(true);
/**
* 设置必须删除元素内容中的空格(有时也可以称作可忽略空格,请参阅 XML Rec 2.10)。
* 注意,只有在空格直接包含在元素内容中,并且该元素内容是只有一个元素的内容模式时,
* 才能删除空格(请参阅 XML Rec 3.2.1)。由于依赖于内容模式,因此此设置要求解析器处于验证模式。默认情况下,其值设置为 false
*/
factory.setIgnoringElementContentWhitespace(false);
/**
* 指定由此代码生成的解析器将把 CDATA 节点转换为 Text 节点,并将其附加到相邻(如果有)的 Text 节点。默认情况下,其值设置为 false
*/
factory.setCoalescing(false);
/**
* 指定由此代码生成的解析器将扩展实体引用节点。默认情况下,此值设置为 true
*/
factory.setExpandEntityReferences(true);
//创建DocumentBuilder实例对象
DocumentBuilder builder = factory.newDocumentBuilder();
//指定使用 EntityResolver 解析要解析的 XML 文档中存在的实体。将其设置为 null 将会导致底层实现使用其自身的默认实现和行为。
builder.setEntityResolver(entityResolver);
//指定解析器要使用的 ErrorHandler。将其设置为 null 将会导致底层实现使用其自身的默认实现和行为。
builder.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException exception) throws SAXException {
throw exception;
}

@Override
public void fatalError(SAXParseException exception) throws SAXException {
throw exception;
}

@Override
public void warning(SAXParseException exception) throws SAXException {
// NOP
}
});
return builder.parse(inputSource);
} catch (Exception e) {
throw new BuilderException("Error creating document instance. Cause: " + e, e);
}
}

private void commonConstructor(boolean validation, Properties variables, EntityResolver entityResolver) {
this.validation = validation;
this.entityResolver = entityResolver;
this.variables = variables;
XPathFactory factory = XPathFactory.newInstance();
this.xpath = factory.newXPath();
}

}


3、实例化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);
}




private final Map<String, Class<?>> typeAliases = new HashMap<>();


对alias进行小写化,将别名作为key,class作为value存入typeAliases这个map中




private final Map<Class<? extends LanguageDriver>, LanguageDriver> LANGUAGE_DRIVER_MAP = new HashMap<>();

public void register(Class<? extends LanguageDriver> cls) {
if (cls == null) {
throw new IllegalArgumentException("null is not a valid Language Driver");
}
MapUtil.computeIfAbsent(LANGUAGE_DRIVER_MAP, cls, k -> {
try {
return k.getDeclaredConstructor().newInstance();
} catch (Exception ex) {
throw new ScriptingException("Failed to load language driver for " + cls.getName(), ex);
}
});
}


MapUtil.computeIfAbsent静态方法


public static <K, V> V computeIfAbsent(Map<K, V> map, K key, Function<K, V> mappingFunction) {
V value = map.get(key);
if (value != null) {
return value;
}
return map.computeIfAbsent(key, mappingFunction::apply);
}


对传入的map进行判断,判断传入的key是否存在于map中,如果存在直接返回;如果不存在,那么就计算后返回------mappingFunction代表我们自定义的函数,如果该函数返回不为空那么就put(key, 函数返回的值),否则不对map进行操作。


4、错误上下文进行赋值


主要作用:对当前线程的 ErrorContext 类的 resource 属性进行赋值


ErrorContext.instance().resource("SQL Mapper Configuration");


/**
* Copyright 2009-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.executor;

/**
* @author Clinton Begin
*/
public class ErrorContext {

private static final String LINE_SEPARATOR = System.lineSeparator();
private static final ThreadLocal<ErrorContext> LOCAL = ThreadLocal.withInitial(ErrorContext::new);

private ErrorContext stored;
private String resource;
private String activity;
private String object;
private String message;
private String sql;
private Throwable cause;

private ErrorContext() {
}

public static ErrorContext instance() {
return LOCAL.get();
}



public ErrorContext resource(String resource) {
this.resource = resource;
return this;
}


public ErrorContext reset() {
resource = null;
activity = null;
object = null;
message = null;
sql = null;
cause = null;
LOCAL.remove();
return this;
}


}


5、parser.json


{
    "configuration": {
        "aggressiveLazyLoading"false,
        "autoMappingBehavior""PARTIAL",
        "autoMappingUnknownColumnBehavior""NONE",
        "cacheEnabled"true,
        "cacheNames": [],
        "caches": [],
        "callSettersOnNulls"false,
        "defaultExecutorType""SIMPLE",
        "defaultScriptingLanguageInstance": {},
        "defaultScriptingLanuageInstance": {},
        "incompleteCacheRefs": [],
        "incompleteMethods": [],
        "incompleteResultMaps": [],
        "incompleteStatements": [],
        "interceptors": [],
        "jdbcTypeForNull""OTHER",
        "keyGeneratorNames": [],
        "keyGenerators": [],
        "languageRegistry": {
            "defaultDriver": {},
            "defaultDriverClass""org.apache.ibatis.scripting.xmltags.XMLLanguageDriver"
        },
        "lazyLoadTriggerMethods": [
            "hashCode",
            "equals",
            "clone",
            "toString"
        ],
        "lazyLoadingEnabled"false,
        "localCacheScope""SESSION",
        "mapUnderscoreToCamelCase"false,
        "mappedStatementNames": [],
        "mappedStatements": [],
        "mapperRegistry": {
            "mappers": []
        },
        "multipleResultSetsEnabled"true,
        "objectFactory": {},
        "objectWrapperFactory": {},
        "parameterMapNames": [],
        "parameterMaps": [],
        "proxyFactory": {},
        "reflectorFactory": {
            "classCacheEnabled"true
        },
        "resultMapNames": [],
        "resultMaps": [],
        "returnInstanceForEmptyRow"false,
        "safeResultHandlerEnabled"true,
        "safeRowBoundsEnabled"false,
        "shrinkWhitespacesInSql"false,
        "sqlFragments": {},
        "typeAliasRegistry": {
            "typeAliases": {
                "date""java.util.Date",
                "_boolean""boolean",
                "cglib""org.apache.ibatis.executor.loader.cglib.CglibProxyFactory",
                "_byte[]""[B",
                "_int[]""[I",
                "object[]""[Ljava.lang.Object;",
                "decimal[]""[Ljava.math.BigDecimal;",
                "integer""java.lang.Integer",
                "float""java.lang.Float",
                "perpetual""org.apache.ibatis.cache.impl.PerpetualCache",
                "_byte""byte",
                "iterator""java.util.Iterator",
                "biginteger[]""[Ljava.math.BigInteger;",
                "xml""org.apache.ibatis.scripting.xmltags.XMLLanguageDriver",
                "_double""double",
                "_int""int",
                "hashmap""java.util.HashMap",
                "_float[]""[F",
                "soft""org.apache.ibatis.cache.decorators.SoftCache",
                "javassist""org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory",
                "date[]""[Ljava.util.Date;",
                "bigdecimal[]""[Ljava.math.BigDecimal;",
                "slf4j""org.apache.ibatis.logging.slf4j.Slf4jImpl",
                "byte""java.lang.Byte",
                "double""java.lang.Double",
                "resultset""java.sql.ResultSet",
                "raw""org.apache.ibatis.scripting.defaults.RawLanguageDriver",
                "collection""java.util.Collection",
                "list""java.util.List",
                "lru""org.apache.ibatis.cache.decorators.LruCache",
                "_float""float",
                "_long""long",
                "_integer""int",
                "_integer[]""[I",
                "boolean[]""[Ljava.lang.Boolean;",
                "decimal""java.math.BigDecimal",
                "_double[]""[D",
                "object""java.lang.Object",
                "biginteger""java.math.BigInteger",
                "string""java.lang.String",
                "long[]""[Ljava.lang.Long;",
                "jdbc""org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory",
                "long""java.lang.Long",
                "weak""org.apache.ibatis.cache.decorators.WeakCache",
                "no_logging""org.apache.ibatis.logging.nologging.NoLoggingImpl",
                "unpooled""org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory",
                "pooled""org.apache.ibatis.datasource.pooled.PooledDataSourceFactory",
                "db_vendor""org.apache.ibatis.mapping.VendorDatabaseIdProvider",
                "managed""org.apache.ibatis.transaction.managed.ManagedTransactionFactory",
                "commons_logging""org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl",
                "_short[]""[S",
                "_short""short",
                "map""java.util.Map",
                "log4j""org.apache.ibatis.logging.log4j.Log4jImpl",
                "jdk_logging""org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl",
                "fifo""org.apache.ibatis.cache.decorators.FifoCache",
                "bigdecimal""java.math.BigDecimal",
                "short[]""[Ljava.lang.Short;",
                "int[]""[Ljava.lang.Integer;",
                "arraylist""java.util.ArrayList",
                "int""java.lang.Integer",
                "float[]""[Ljava.lang.Float;",
                "log4j2""org.apache.ibatis.logging.log4j2.Log4j2Impl",
                "byte[]""[Ljava.lang.Byte;",
                "boolean""java.lang.Boolean",
                "stdout_logging""org.apache.ibatis.logging.stdout.StdOutImpl",
                "double[]""[Ljava.lang.Double;",
                "_long[]""[J",
                "jndi""org.apache.ibatis.datasource.jndi.JndiDataSourceFactory",
                "short""java.lang.Short",
                "_boolean[]""[Z",
                "integer[]""[Ljava.lang.Integer;"
            }
        },
        "typeHandlerRegistry": {
            "typeHandlers": [
                {
                    "rawType""java.math.BigDecimal"
                },
                {
                    "rawType""[Ljava.lang.Byte;"
                },
                {
                    "rawType""java.lang.String"
                },
                {
                    "rawType""java.util.Date"
                },
                {
                    "rawType""java.time.OffsetTime"
                },
                {
                    "rawType""java.time.Year"
                },
                {
                    "rawType""java.time.chrono.JapaneseDate"
                },
                {
                    "rawType""java.util.Date"
                },
                {
                    "rawType""java.math.BigInteger"
                },
                {
                    "rawType""java.time.LocalDateTime"
                },
                {
                    "rawType""java.time.LocalTime"
                },
                {
                    "rawType""java.lang.String"
                },
                {
                    "rawType""java.lang.Integer"
                },
                {
                    "rawType""java.lang.String"
                },
                {
                    "rawType""java.time.LocalDate"
                },
                {
                    "rawType""java.lang.Character"
                },
                {
                    "rawType""java.lang.Short"
                },
                {
                    "rawType""java.io.Reader"
                },
                {
                    "rawType""java.lang.Boolean"
                },
                {
                    "rawType""java.lang.String"
                },
                {
                    "rawType""java.time.Month"
                },
                {
                    "rawType""java.sql.Time"
                },
                {
                    "rawType""[Ljava.lang.Byte;"
                },
                {
                    "rawType""java.lang.Double"
                },
                {
                    "rawType""java.lang.String"
                },
                {
                    "rawType""java.lang.Object"
                },
                {
                    "rawType""java.sql.Timestamp"
                },
                {
                    "rawType""java.time.YearMonth"
                },
                {
                    "rawType""java.lang.Byte"
                },
                {
                    "rawType""java.time.ZonedDateTime"
                },
                {
                    "rawType""[B"
                },
                {
                    "rawType""[B"
                },
                {
                    "rawType""java.time.Instant"
                },
                {
                    "rawType""java.lang.Float"
                },
                {
                    "rawType""java.sql.Date"
                },
                {
                    "rawType""java.time.OffsetDateTime"
                },
                {
                    "rawType""java.lang.Long"
                },
                {
                    "rawType""java.lang.Object"
                },
                {
                    "rawType""java.util.Date"
                },
                {
                    "rawType""java.io.InputStream"
                }
            ],
            "unknownTypeHandler": {
                "rawType""java.lang.Object"
            }
        },
        "useActualParamName"true,
        "useColumnLabel"true,
        "useGeneratedKeys"false
    }
}



6、解析environments标签




6、解析mappers标签












相关推荐

评论 抢沙发

表情

分类选择