前言
每一个 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 可以说SqlSessionFactory贯彻整个MyBatis。
<configuration>
<settings>
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!--<objectFactory type="com" >-->
<!--<property name="" value=""></property>-->
<!--</objectFactory>-->
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/clyu"/>
<property name="username" value="root"/>
<property name="password" value="YCLh2o2@"/>
</dataSource>
</environment>
</environments>
<!-- 加载mapper.xml -->
<mappers>
<mapper resource="mapper/PersonMapper.xml"/>
</mappers>
</configuration>
String resource = "mybatis-config.xml";
try (
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//这里使用了工厂设计模式
SqlSession session = sqlSessionFactory.openSession();
) {
PersonMapper mapper = session.getMapper(PersonMapper.class);
}
这段代码,相信看过MyBatis的人都很熟悉,本文就是从new SqlSessionFactoryBuilder().build(inputStream);
开始
开始
SqlSessionFactoryBuilder使用的是默认的构造方法,所以只需关注他的build方法
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
//会使用dom4j解析mybatis-config.xml。
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
// 解析config.xml里面的节点 :重点
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.
}
}
}
public class XMLConfigBuilder extends BaseBuilder {
public Configuration parse() {
if (parsed) { //配置文件只能解析一次
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
//从configuration节点开始解析配置文件
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
private void parseConfiguration(XNode root) {
try {
//properties配置是用来配置连接数据库的信息,
propertiesElement(root.evalNode("properties"));
//settings配置,会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
//日志配置logImpl
loadCustomLogImpl(settings);
//处理别名,放到一个map中
typeAliasesElement(root.evalNode("typeAliases"));
//插件
pluginElement(root.evalNode("plugins"));
//objectFactory自定义实例化对象的行为
objectFactoryElement(root.evalNode("objectFactory"));
//MateObject 方便反射操作实体类的对象
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);
}
}
通过以上源码,我们就能看出,在mybatis的配置文件中:
-
configuration节点为根节点。
-
在configuration节点之下,我们可以配置10个子节点, 分别为:properties、typeAliases、plugins、objectFactory、objectWrapperFactory、settings、environments、databaseIdProvider、typeHandlers、mappers。
本篇文章就先只介绍这些内容,接下来的文章将依次分析解析这个10个节点中比较重要的几个节点的源码,看看在解析这些节点的时候,到底做了些什么。