Mybatis流程分享-I 配置文件解析

Mybatis流程分享-I 配置文件解析

序言

如果要使用Mybatis来对数据库进行操作,我们需要先准备Mybatis对应的配置文件。具体来看,我们要完成对数据库的操作,需要告诉Mybatis框架数据库的用户名,地址,端口,密码等。此外,我们需要创建映射器接口和相对应的xml文件。

image-20230919165416220

Mybatis 加载流程

当我们配置完Mybatis的配置文件后,实际就是将数据库的信息告诉Mybatis框架,在这个阶段,我们通常会编写以下的代码

String resource = "org/mybatis/example/mybatis-config.xml";
//Step1. 加载配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//Step2. 创建sessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//Step3. 通过sessionFactory获取一个SqlSession对象
SqlSession sqlSession = sessionFactory.openSession();
//Step4. 通过ClassType获取对应的代理接口
IUerService uerService = sqlSession.getMapper(IUerService.class);
//Step5. 通过代理对象执行对应相应方法
System.out.println(uerService.getUserNameById("11111"));

而上述代码的逻辑就是

  1. 通过SqlSession工厂构造器构造一个SqlSessiionFactory对象
  2. 通过SqlSessionFactory对象获取一个SqlSessioin对象
  3. 向SqlSession中传入一个Mapper接口,获取到一个Mapper接口的代理对象
  4. 通过代理对象,执行相应的方法,从而执行对应的SQL语句

观察上述代码,我们发现从Step1,Step2这两步中,我们会将配置好的xml信息传入到Mybatis中,所以接下来对这两步入手,分析Mybatis对这个地方做出了哪些处理

资源文件预加载处理

在Step1中,会通过Resources.getResourceAsStream(resource) 来获取一个输入流对象,在这个地方只是单纯把文件转成 InputStream 输入流

我们需要关注的是Step2中 SqlSessionFactoryBuilder 是怎么处理这个InputStream 输入流的, 其源码如下

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
//构建一个XMLConfigBuilder对象
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
} catch (Exception e) {
.......
}

可以看到,Build()方法中,会通过传入的InputStream方法创建一个XMLConfigBuilder类,然后去调用parse方法进行解析。

配置文件解析的工具 - XMLConfigBuilder

这个类我们之前可能没见过,不知道其功能是什么,但是从整体来看,它出现在了Step1,Step2中,而这两步的作用是

  1. 配置Mybatis所需的配置文件信息
  2. 加载配置文件信息,解析配置文件,构建接口代理对象

具体来说,它出现在Step2,解析配置文件,构建接口代理对象这一步,所以我们猜想这个类的主要功能就是对配置文件进行解析。我们可以进入parse()方法中一探究竟

/**
* 解析配置文件的入口方法
* @return Configuration对象
*/
public Configuration parse() {
// 不允许重复解析
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
// 从根节点开展解析
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
/**
* 从根节点configuration开始解析下层节点
* @param root 根节点configuration节点
*/
private void parseConfiguration(XNode root) {
try {
// 解析信息放入Configuration
// 首先解析properties,以保证在解析其他节点时便可以生效
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
loadCustomLogImpl(settings);
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
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);
}
}

可以看到,我们可以看到这XMLConfigBuilder会先对配置文件下的根节点 "/configuration" 开始进行展开,进而进行解析,而这些节点可以在xml进行选择性的配置 Mybatis XML配置 ,这些配置信息最终都会被加载到Configuration 这个类中。

然后通过通过返回的configration构建一个默认的SqlSession返回。

至此,我们就大概了解到了Mybatis对于配置文件的解析全过程,其整体细节如下

image-20230919182120319

事实上,对于Mybatis的加载过程来说,其在处理配置文件信息时,首先,会传递配置文件所在位置信息,然后再调用框架提供的SqlSessionFactorybuild方法便会根据传入路径信息去加载相关的配置文件,并进行解析。而解析的内容会存放到的configuration之中,进而方便后续组件的使用。

posted @   Violet-EV  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
Language: HTML
点击右上角即可分享
微信分享提示