0%

MyBatis 配置文件加载流程分析

MyBatis 是一款半自动化的 ORM(Object Relational Mapping:对象关系映射)框架,帮我们消除了大量的 JDBC 冗余代码,包括参数的设置,结果集的封装等,能够将数据库中的记录转换为 Java 实体。这篇文章会通过源码的角度分析 MyBatis 加载配置文件的流程。

先通过一张图来看看 MyBatis 是如何运行的吧:

在这过程中,MyBatis 会帮我们处理数据库表与 Java 实体的映射关系:

1
2
3
数据库的表(table) --> 类(class)
记录(record,行数据)--> 对象(object)
字段(field)--> 对象的属性(attribute)

MyBatis 当中的配置及其使用回顾

在分析具体的加载流程前,我们先来回顾一下 MyBatis 的使用步骤:
1、一般情况我们会有一个主配置文件,当中配置了数据库连接信息、数据库表对应实体类别名、类型处理器、插件、SQL 映射文件Mapper.xml 等信息。文件以 configuration 标签开头。标签如下所示(具体的配置(略)):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<configuration>
<properties resource=""/>
<!--是否使用缓存、懒加载、自动生成主键等配置-->
<settings></settings>
<!--实体类别名配置-->
<typeAliases></typeAliases>
<!--类型处理器配置-->
<typeHandlers></typeHandlers>
<!--插件配置-->
<plugins></plugins>
<!--相关环境配置,包括数据库连接等信息-->
<environments default="development"></environments>
<!--Mapper文件信息配置-->
<mappers></mappers>
</configuration>

2、编写数据库表对应的实体类,将数据库表字段映射成Java类中的属性。
3、编写 Mapper 接口和对应的 Mapper.xml 文件,并在 Mapper 当中书写相应的 SQL 语句。以下是 Mapper 文件中的相关标签及其作用:

1
2
3
4
5
6
7
8
9
10
11
<!--namespace:所对应的Mapper接口-->
<mapper namespace="org.apache.ibatis.domain.blog.mappers.AuthorMapper">
<!--查询参数Map-->
<parameterMap> </parameterMap>
<!--结果集字段映射-->
<resultMap></resultMap>
<!--SQL语句-->
<select id="selectAllAuthorsLinkedList" resultType="org.apache.ibatis.domain.blog.Author">
select * from author
</select>
</mapper>

配置文件的加载与解析流程

在日常开发中,我们也会发现在程序启动时会先将以上的配置文件先加载到内存并进行解析;可以通过 MyBatis 的一段单元测试来了解其中的流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static SqlSessionFactory sqlSessionFactory;

@BeforeAll
static void setUp() throws Exception {
// create a SqlSessionFactory
try (
//读取配置文件
Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/no_param_type/mybatis-config.xml"));
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}

// populate in-memory database
BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
"org/apache/ibatis/submitted/no_param_type/CreateDB.sql");
}

经过调试,可以看出大致的流程如下:
将主配置文件加载进内存,生成字符流 –> 使用 XPath 对 XML 进行解析,转成可解析的 XMLConfigBuilder 对象 –> 将信息解析成Configuration对象,通过配置信息 Configuration 构建 SqlSessionFactory 对象。

  • 具体的调用链如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//1、生成XMLConfigBuilder对象(主要使用工具对xml文件进行解析):包含 Document 文档对象
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
//2、解析配置文件,生成Configuration对象
public Configuration parse() {
...部分代码省略...
//标签解析
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
//对各种标签的解析与处理代码
private void parseConfiguration(XNode root) {
try {
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
//对Mappers标签进行解析
mapperElement(root.evalNode("mappers"));
...部分代码省略...
}
//对Mapper.xml文件进行解析,并注册Mapper文件信息
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();
configurationElement(parser.evalNode("/mapper"));
configuration.addMapper(boundType);

总结:xml 文件配置信息经过加载,解析,最终会解析成 Configuration 对象以供程序后续的使用。