
Mybatis configuration 核心构建流程
01、Configuration 创建
在之前解析 SqlSessionFactory 的时候, build() 实现并没有详细解读, 而今天源码解析的主人公 Configuration 就在此方法中被初始化
这里以字节流的 build() 重载方法构建举例
02、XMLConfigBuilder
主要用于解析 mybatis 的 xml 配置文件,并将解析结果存放到 Configuration 对象, 得到 Configuration 对象后创建 SqlSessionFactory
XMLConfigBuilder 继承自抽象类 BaseBuilder 使用的建造者设计模式, 有兴趣可以了解下
parser.parse() 返回值为 Configuration 对象, 被定义在了 BaseBuilder
在 XMLConfigBuilder 构造方法中进行了 configuration 的初始化工作, 初始化的步骤在下面介绍
2.1 入参 XPathParser
XPathParser 是一个 xml 解析器, 具体解析器如果构建的就不描述了
2.2 入参 environment
这个参数为了保证多环境配置, 具体在 <environments> 中配置
在 Configuration 的 parse() 方法中会解析传入的 environment 参数, 根据参数解析出 <environments> 标签下对应的 environment 标签
“如果在 environments 标签下只有一个 environment, 而且在build()中没有指定environment; 那么一定要把 id 定义为 development, 别问我怎么知道的, NPE 真香~
这段代码是解析 mybatis-config.xml 配置文件中 environments 标签的代码
2.3 入参 Properties
Properties 是一个继承了 Hashtable 形式的 key val 存储结构
在配置文件中定义 Properties, 分为两种方式: 文件引入、标签直接定义
直接在相关位置定义
引入 properties 类型配置
而代码中定义也比较简单
可以在 mybatis 创建 SqlSessionFactory 时的 build(inputStream, properties) 传入
如果配置文件有 Properties 标签, build 方法也传入了 Properties 对象, 遇到相同 key 时会按照哪个呢?
实际以 XMLConfigBuilder 解析方法为准, 上源码
到这也清楚了, build 方法传入 Properties 参数会覆盖配置文件中定义的
03、Configuration 初始化
通过上面分析得知 Configuration 初始化操作在 XMLConfigBuilder
接下来看 Configuration 初始化时做了哪些动作
总体而言 Configuration 初始化过程分为两大块
- 向 typeAliasRegistry 注册别名以及对应的内容
- 向 languageRegistry 注册 SQL 解析器并设置默认
3.1 TypeAliasRegistry
什么是类型别名 typeAlias
像 mysql、oracle 等数据库都支持别名方式, mybatis 也提供了这种机制
mybatis 中类型别名就是针对 mybatis 中常用的类型进行别名设置, 使用别名来代替具体的类型
在 mybatis 中使用 key, val 结构存放别名和实体之间的关联关系
类型别名的用途是什么
类型别名在 mybatis 中主要用于取代复杂的类型全限定名, 用于映射器配置文件中进行参数类型与返回结果类型的设置
mybatis 会在进行数据库操作之前进行参数类型别名的解析操作获取具体的参数类型, 又会在数据库操作之后进行结果类型别名的解析获取具体的结果类型
TypeAliasRegistry 初始化
在 TypeAliasRegistry 默认构造方法中将一些基本类型和其对应的引用类型进行了预置(包括相对应的数组)
自定义类型别名
除了上面所说在构造方法中预置的内容, 在项目中也可以通过 mybatis 配置文件进行配置
typeAlias 标签中的 alias 属性表示 别名, type 表示具体类型全限定名
别名方式大家其实都有用过, 看一下实际中使用的; artCon 就是别名, 会配置相对应的具体类型
具体还可以通过扫描包名和配置注解的方式注册, 这里就不再赘述了
注册别名类型
在 TypeAliasRegistry 中有多个向容器存放别名的重载方法 registerAlias(), 但是真正去向容器 put 的只有一个, 这里简要分析一下
3.2 LanguageDriverRegistry
LanguageDriverRegistry 是 myabtis 中的 SQL 解析容器, 将不同的 SQL 解析器进行存储, 与 TypeAliasRegistry 一致都是 HashMap 存储方式
Configuration 初始化时将两种不同的解析器注册到了 LanguageDriverRegistry
XMLLanguageDriver
mybatis 默认解析器, 主要作用于解析 select | update | insert | delete 节点为完整的 SQL 语句, 包括解析 <where>、<if>、<otherwise>、<when> 等动态标签, 最终创建 DynamicSqlSource
RawLanguageDriver
RawLanguageDriver 处理静态 sql, 创建出 RawSqlSource
静态 SQL 就是不包含动态标签的 SQL, 举例:
“SQL 标签如何解析会单独拉篇文章来讲, 因为这一块也比较感兴趣的
04、解析 mybatis-config.xml
4.1 parser.parse()
上面将 XMLConfigBuilder 的初始化以及对 Configuration 的初始化
下面来说下是如何解析 mybatis-config.xml 文件, 并如何为 Configuration 对象赋值的
点进去看一下 parse() 方法的具体实现
4.2 parseConfiguration(xnode)
方法就是为了解析 mybatis-config.xml, 解析出各个标签并存储到 Configuration 对象
有没有小伙伴比较疑惑, evalNode("xxx") 都是固定的, 这些值是从哪里来的呢这里就清楚明了了, 因为 mybatis-config.xml 仅支持这 11 个标签
至此关于 Configuration 的初始化以及关键对象赋值已说明; 里面存的属性太多了...
具体的解析步骤就不一一描述了, 思路就是解析标签名称, 看是否存在, 存在进行迭代相关标签, 将对应的内容赋值 Configuration
关于对象中的变量对象, 会单独写一篇文章
05、结语
个人感觉 写文章挺有帮助, 写的过程相当于又 巩固了一遍, 而且会强迫自己说一些 通俗易懂的话, 对于之前感觉理解的内容做到 真正理解
看源码是个 枯燥的过程, 如果想学习 mybatis 框架源码, 建议先看些 相关源码视频或者书籍, 这样在你脑海中会存在一个 整体架构图
在最开始看源码时, 不能明白作者的设计; 看过视频和书籍之后, 再回首看源码的时候, 会有一种原来如此的感觉
最后总结一句话: 纸上得来终觉浅, 绝知此事要躬行.
本文转载自微信公众号「龙台的技术笔记」
