Mybatis(三):架构及解析器模块详解
文章目录
在前面的文章中我们了解了
Mybatis
的基本使用及其执行流程。相信你已经对
Mybatis
有了简单的了解。
今天我们正式进去源码学习阶段,在这篇文章中,我们首先介绍下Mybatis
的结构,之后再学习下解析器模块的内容。
首先自行去github
上下载其源码,地址为:https://github.com/mybatis/mybatis-3
为方便查看,我们将下载的源码导入到idea
中,Mybaits
的项目结构还是比较清晰明了的,目录如下所示:
1 架构
通过Mybatis
的源码我们发现,Mybatis
将其模块分成了一个个的包,我们可以很清楚的知道其有哪些模块组成,接下来我们依次简单的介绍下这些模块:
annotations
注解 这个没什么可说的,Mybatis
中的一些注解定义在了这个包里,例如:@Select @Insert @Update...
io
这个模块主要负责资源的加载,在上篇文章中提到的Resources
类便是定义在这个模块下。parsing
解析器XPathParser
封装了对xml文件的解析。builder
配置解析模块 解析Mybatis
配置文件及映射文件,将里面的信息封装到Configuration
对象中。parsing
解析器 这个模块的功能是负责我们定义的配置文件及映射文件的解析。XPathParser
。binding
这个模块是负责将Mapper
中的方法同xml
文件中相关的SQL
进行关联,MapperRegistry
、MypperProxyFactory
、MypperProxy
、MapperMethod
都是定义在这个模块下。cache
缓存 使用Mybatis
的同学应该都知道其有一级和二级缓存,这些功能便定义在这个模块中,有了缓存的存在,能够提高一些查询的性能,但如果在开发中不注意的话也会导致一些问题。cursor
游标datasource
数据源模块executor
执行器模块 负责SQL
的执行及结果的映射。transaction
事务logging
日志模块mapping
mapper对应的java类plugin
插件reflection
反射scripting
动态sql
解析type
类型处理器session
sql会话
Mybatis
的架构由接口层、核心处理层、基础支持层三部分组成。各层的组成模块如下图所示。
2 解析器模块
解析器模块为Mybatis
初始化时加载配置文件和mapper映射文件解析及动态SQL
占位符的处理提供了支持。
Mybatis
解析器模块的目录如下:
2.1 XPathParser
XPathParser
是Mybatis
中的解析器,其对XPath
进行了封装,其属性字段如下:
Document document
Document
对象boolean validation
是否校验xml
EntiryResolver entityResolver
Properties variables
属性XPath xpath
Xpath
对象
2.1.1 构造方法
在XPathParser
中提供了很多个构造方法,这里就不进行列举了,在这些方法中没有过多的逻辑,就是创建Document
和XPath
对象并设置其他属性字段。
在其构造方法中会调用到commonConstructor
和createDocument
两个方法,其源码如下:
private void commonConstructor(boolean validation, Properties variables, EntityResolver entityResolver) {
// 设置是否校验XML
this.validation = validation;
// EntityResolver用于解析本地DTD或XSD
this.entityResolver = entityResolver;
// 配置文件中配置的properties
this.variables = variables;
// 创建XPath对象
XPathFactory factory = XPathFactory.newInstance();
this.xpath = factory.newXPath();
}
private Document createDocument(InputSource inputSource) {
// important: this must only be called AFTER common constructor
try {
// 创建DocumentBuilderFactory对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
// 是否校验
factory.setValidating(validation);
// 设置其他一些属性
factory.setNamespaceAware(false);
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(false);
factory.setCoalescing(false);
factory.setExpandEntityReferences(true);
// 创建DocumentBuilder对象
DocumentBuilder builder = factory.newDocumentBuilder();
// 设置EntityResolver
builder.setEntityResolver(entityResolver);
builder.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException exception) throws SAXException {