前言
上面那篇文章我们知道Mybatis和数据库的交互方式有Java和Mapper接口两种,所以Mybatis的初始化方式必然也有两种;本篇我们开始对Mybatis的初始化过程进行详细讲解
- 基于XML配置文件:基于XML配置文件的方式是将Mybatis的所有配置放在XML文件中,Mybatis通过加载XML配置文件,将配置文信息组装成内部的Configuration对象
- 基于Java API:这种方式不使用XML配置文件,需要Mybatis使用者在Java代码中,手动创建Configuration对象,然后将配置参数set入该对象
XML配置——初始化
我们将通过基于XML配置文件方式的Mybatis初始化,深入探讨Mybatis是如何配置文件构建Configuration对象的
// mybatis初始化
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 执行SQL
List list = sqlSession.selectList("com.alibaba.tao.xx");
这是一个简单的执行 com.alibaba.tao.xx SQL查询的语句:
经历了三个阶段:
- mybatis初始化
- 创建SqlSession
- 执行SQL语句
上述代码主要的功能是根据配置文件mybatis-config.xml配置文件,创建SqlSessionFactory对象,然后产生SqlSession,执行SQL语句。而mybatis的初始化就发生在第三句:new SqlSessionFactoryBuilder().build(inputStream);我们看看第三句发生了什么:
Mybatis初始化基本过程
SqlSessionFactorBuilder根据传入的数据流生成Configuration对象,然后根据Configuration对象创建默认的SqlSessionFactor对象,时序图如下:

由上图可以看出,mybatis初始化要经过简单的以下几个步:
-
调用SqlSessionFactorBuilder对象的build(inputStream)方法;
-
SqlSessionFactorBuilder根据输入流inputStream等信息创建XMLConfigBuilder对象;
-
SqlSessionFactorBuilder调用XMLConfigBuilder对象的parse()方法;
-
XMLConfigBuilder返回Configuration对象;
-
SqlSessionFactorBuilder根据Configuration对象创建一个DefaultSessionFactory对象;
-
SqlSessionFactoryBuilder返回 DefaultSessionFactory对象给Client,供Client使用。
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
//1. 创建XMLConfigBuilder对象用来解析XML配置文件,生成Configuration对象
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
//2. 将XML配置文件内的信息解析成Java对象Configuration对象
Configuration config = parser.parse();
//3. 根据Configuration对象创建出SqlSessionFactory对象
return build(config);
} 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.
}
} }// 从此处可以看出,MyBatis内部通过Configuration对象来创建SqlSessionFactory,用户也可以自己通过API构造好Configuration对象,调用此方法创SqlSessionFactory
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
上面的代码有一个很重要的类:XMLConfigBuilder,将mybatis-config.xml配置文件解析成Configuration对象,供SqlSessionFactoryBuilder使用,创建SqlSessionFactory,下面重点讲解是如何创建的
创建Configuration对象
现在我们开始分析下parse()方法是如何处理XML文件,生成Configuration对象
先看下Mybatis的配置文件示例
详细的配置信息解释见:www.cnblogs.com/BlogNetSpac…
<configuration>
<?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="db.properties" />
<typeAliases>
<typeAlias type="com.example.User" alias="User" />
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml" />
</mappers>
</configuration>
再看下源码
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
//1.先将xml以及配置文件转换成对应的document对象,构成XNode树结构
//2.从中解析里面的子Node:properties、typeAliases、plugins等
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
/**
* 解析 "/configuration"节点下的子节点信息,然后将解析的结果设置到Configuration对象中
*/
private void parseConfiguration(XNode root) {
try {
//1.首先处理properties 节点
propertiesElement(root.evalNode("properties")); //issue #117 read properties first
//2.处理typeAliases
typeAliasesElement(root.evalNode("typeAliases"));
//3.处理插件
pluginElement(root.evalNode("plugins"));
//4.处理objectFactory
objectFactoryElement(root.evalNode("objectFactory"));
//5.objectWrapperFactory
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
//6.settings
settingsElement(root.evalNode("settings"));
//7.处理environments
environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631
//8.database
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
//9.typeHandlers
typeHandlerElement(root.evalNode("typeHandlers"));
//10.mappers
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
上述代码中,我们可以看出,在配置文件中,代码逐渐对以下节点进行解析:
- configuration节点为根节点。
- 在configuration节点之下,可以配置10个子节点, 分别为:properties、typeAliases、plugins、objectFactory、objectWrapperFactory、settings
篇章问题,各个节点解析过程暂不展开赘述
其中,mapperElement(root.evalNode("mappers")); 就是解析XML配置文件子节点的方法,后面篇章展开讲解。
相关的时许图参考如下

基于Java API—初始化
下面是一个基于API方式初始化示例,可以看出就是使用使用XMLConfigBuilder手动解析XML配置文件来创建Configuration对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 手动创建XMLConfigBuilder,并解析创建Configuration对象
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, null,null); // 看这里
Configuration configuration = parser.parse();
// 使用Configuration对象创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
// 使用MyBatis
SqlSession sqlSession = sqlSessionFactory.openSession();
List list = sqlSession.selectList("com.alibaba.tao.xx");