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 @ 2024-02-27 00:29  Violet-EV  阅读(49)  评论(0)    收藏  举报
Language: HTML