<?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?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?-->
<!-- settings -->
<settings>
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 将积极加载改为消极加载(即按需加载) -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 打开全局缓存开关(二级缓存)默认值就是 true -->
<setting name="cacheEnabled" value="true"/>
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
<!-- 别名定义 -->
<typeAliases>
<package name="cn.fzkj.entity"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<!-- 通过 resource 方法一次加载一个映射文件 -->
<mapper resource="mybatis/UserMapper.xml"/>
<!-- 批量加载mapper -->
<!-- <package name="cn.fzkj.mapper"/>-->
</mappers>
</configuration>
public static void main(String[] args) {
String resource = "mybatis-config.xml";
SqlSession sqlSession = null;
// 将xmybatis配置文件加载到内存
try(InputStream in = Resources.getResourceAsStream(resource)){
// 创建SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 创建SqlSessionFactory
SqlSessionFactory factory = builder.build(in);
// 创建SqlSession
sqlSession = factory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
System.out.println(mapper.selectUserById(2));
}catch (Exception e) {
e.printStackTrace();
}finally {
sqlSession.close();
}
}
1、加载配置文件
Resources.getResourceAsStream(resource)
这一步会将mybaits的配置文件内容读进内存。
2、创建SqlSessionFactory
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
现在从xml中创建了一个SqlSessionFactoryBuilder。然后会创建出SqlSessionFactory。
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
SqlSessionFactory var5;
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
// 解析xml文件
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException var13) {
}
}
return var5;
}
public SqlSessionFactory build(Configuration config) {
// 使用创建好的configuration对象创建出SqlSessionFactory
return new DefaultSqlSessionFactory(config);
}
2.1、解析xml
parser.parse()方法最终会调用到parseConfiguration方法。这个方法中会解析再mybatis配置文件中的所有配置项,并初始化Configuration对象。
private void parseConfiguration(XNode root) {
try {
Properties settings = this.settingsAsPropertiess(root.evalNode("settings"));
this.propertiesElement(root.evalNode("properties"));
this.loadCustomVfs(settings);
this.typeAliasesElement(root.evalNode("typeAliases"));
this.pluginElement(root.evalNode("plugins"));
this.objectFactoryElement(root.evalNode("objectFactory"));
this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
this.reflectorFactoryElement(root.evalNode("reflectorFactory"));
this.settingsElement(settings);
this.environmentsElement(root.evalNode("environments"));
this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
this.typeHandlerElement(root.evalNode("typeHandlers"));
this.mapperElement(root.evalNode("mappers"));
} catch (Exception var3) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
}
}
2.2、初始化Configuration对象
在this.settingsElement(settings);方法中会初始化Configuration对象中的setting配置项。
private void settingsElement(Properties props) throws Exception {
this.configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL")));
this.configuration.setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.valueOf(props.getProperty("autoMappingUnknownColumnBehavior", "NONE")));
this.configuration.setCacheEnabled(this.booleanValueOf(props.getProperty("cacheEnabled"), true));
this.configuration.setProxyFactory((ProxyFactory)this.createInstance(props.getProperty("proxyFactory")));
this.configuration.setLazyLoadingEnabled(this.booleanValueOf(props.getProperty("lazyLoadingEnabled"), false));
this.configuration.setAggressiveLazyLoading(this.booleanValueOf(props.getProperty("aggressiveLazyLoading"), true));
this.configuration.setMultipleResultSetsEnabled(this.booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true));
this.configuration.setUseColumnLabel(this.booleanValueOf(props.getProperty("useColumnLabel"), true));
this.configuration.setUseGeneratedKeys(this.booleanValueOf(props.getProperty("useGeneratedKeys"), false));
this.configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
this.configuration.setDefaultStatementTimeout(this.integerValueOf(props.getProperty("defaultStatementTimeout"), (Integer)null));
this.configuration.setDefaultFetchSize(this.integerValueOf(props.getProperty("defaultFetchSize"), (Integer)null));
this.configuration.setMapUnderscoreToCamelCase(this.booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false));
this.configuration.setSafeRowBoundsEnabled(this.booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false));
this.configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION")));
this.configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER")));
this.configuration.setLazyLoadTriggerMethods(this.stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString"));
this.configuration.setSafeResultHandlerEnabled(this.booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true));
this.configuration.setDefaultScriptingLanguage(this.resolveClass(props.getProperty("defaultScriptingLanguage")));
this.configuration.setCallSettersOnNulls(this.booleanValueOf(props.getProperty("callSettersOnNulls"), false));
this.configuration.setUseActualParamName(this.booleanValueOf(props.getProperty("useActualParamName"), false));
this.configuration.setLogPrefix(props.getProperty("logPrefix"));
Class<? extends Log> logImpl = this.resolveClass(props.getProperty("logImpl"));
this.configuration.setLogImpl(logImpl);
this.configuration.setConfigurationFactory(this.resolveClass(props.getProperty("configurationFactory")));
}