mybatis源码-解析配置文件(一)之XML的DOM解析方式
@
简介
在之前的文章《mybatis 初步使用(IDEA的Maven项目, 超详细)》中, 讲解了mybatis的初步使用, 并总结了以下mybatis的执行流程:
- 通过 Resources 工具类读取 mybatis-config.xml, 存入 Reader;
- SqlSessionFactoryBuilder使用上一步获得的reader创建SqlSessionFactory对象;
- 通过 sqlSessionFactory 对象获得SqlSession;
- SqlSession对象通过selectList方法找到对应的“selectAll”语句, 执行SQL查询。
- 底层通过 JDBC 查询后获得ResultSet, 对每一条记录, 根据resultMap的映射结果映射到Student中, 返回List。
- 最后记得关闭 SqlSession
本系列文章深入讲解第 2 步, 解析配置文件。
Java 中 XML 文件解析
mybatis是基于 XML 来进行配置的, 因此, 我们首先要知道在Java中, XML是如何解析的。
解析方式
XML 常见的解析方式有以下三种: DOM、 SAX 和 StAX。
1. DOM 方式
DOM 基于树形结构解析, 它会将整个文档读入内存并构建一个 DOM 树, 基于这棵树的结构对各个节点进行解析。
2. SAX 方式
SAX 是基于事件模型的 XML 解析方式, 它不需要将整个 XML 文档加载到内存中, 而只需要将一部分 XML 文档的一部分加载到内存中, 即可开始解析。
3. StAX 方式
StAX 与 SAX 类似, 也是把 XML 文档作为一个事件流进行处理, 但不同之处在于 StAX 采用的是“拉模式”, 即应用程序通过调用解析器推进解析的过程。
DOM 解析 XML
在加载 mybatis-config.xml 配置文件与映射文件时, 使用的是 DOM 解析方式, 并配合使用 XPath 解析 XML 配置文件。
XPath 之于 XML 就好比 SQL 之于数据库。
所谓DOM, 是 Document Object Model 的缩写, 翻译过来就是文档对象模型。
下面我们就来展示一下该过程。
新建 XML 文件
<CATALOG>
<CD id="1">
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD id="2">
<TITLE>Hide your heart</TITLE>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
<CD id="3">
<TITLE>Greatest Hits</TITLE>
<ARTIST>Dolly Parton</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>RCA</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1982</YEAR>
</CD>
<CD id="4">
<TITLE>Still got the blues</TITLE>
<ARTIST>Gary Moore</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>Virgin records</COMPANY>
<PRICE>10.20</PRICE>
<YEAR>1990</YEAR>
</CD>
<CD id="5">
<TITLE>Eros</TITLE>
<ARTIST>Eros Ramazzotti</ARTIST>
<COUNTRY>EU</COUNTRY>
<COMPANY>BMG</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1997</YEAR>
</CD>
</CATALOG>
在CATALOG中, 有很多CD, CD有着自己的子节点。
DOM 操作相关类
以上的XML, 其对应的树形结构如下:
而在Java中, 有很节点类型, 以下有几个主要的接口对应着XML中的各个属性。
- Node : DOM最基本的数据类型。 表示文档树中的单个节点
- Element:常见的元素节点
- Attr:代表元素的属性
- Text:元素或者Att的值(内容)
- Document:代表整个XML文档
Java 读取 XML 文件
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException {
// 获取 DocumentBuilderFactory
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setValidating(false);
builderFactory.setNamespaceAware(false);
builderFactory.setIgnoringComments(true);
builderFactory.setIgnoringElementContentWhitespace(false);
builderFactory.setCoalescing(false);
builderFactory.setExpandEntityReferences(true);
// 通过 DocumentBuilderFactory 获取 DocumentBuilder
DocumentBuilder builder = builderFactory.newDocumentBuilder();
builder.setErrorHandler(new ErrorHandler() {
@Override
public void warning(SAXParseException exception) throws SAXException {
System.out.println("warning:"+exception.getMessage());
}
@Override
public void error(SAXParseException exception) throws SAXException {
System.out.println("error:"+exception.getMessage());
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
System.out.println("fatalError:"+exception.getMessage());
}
});
// 得到Document文件, 就是XML在JVM中的化身
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("xml/cds.xml");
Document document = builder.parse(is);
// 以下通过 XPath 来获取对应的信息
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
// 解析 //CD//TITLE//text() , 就是获取所有CD节点下TITLE子节点的文字内容
XPathExpression expression = xPath.compile("//CD//TITLE//text()");
Object result = expression.evaluate(document, XPathConstants.NODESET);
NodeList nodeList = (NodeList)result;
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getNodeValue());
}
}
其主要步骤:
- 创建
DocumentBuilderFactory对象; - 通过
DocumentBuilderFactory创建DocumentBuilder对象; - 通过
DocumentBuilder, 从文件或流中创建通过Document对象; - 创建
XPathFactory对象, 并通过XPathFactory创建XPath对象; - 通过
XPath解析出XPathExpression对象; - 使用
XPathExpression在文档中搜索出相应的节点。
输出结果如下:
也可以调用相应的 API 进行获取和设置各个属性, 在此就不过多的进行深入。
一起学 mybatis
你想不想来学习 mybatis? 学习其使用和源码呢?那么, 在博客园关注我吧!!
我自己打算把这个源码系列更新完毕, 同时会更新相应的注释。快去 star 吧!!

mybatis源码-解析配置文件(一)之XML的DOM解析方式的更多相关文章
- MyBatis 源码分析 - 配置文件解析过程
* 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...
- Mybatis源码阅读-配置文件及映射文件解析
Mybatis源码分析: 1.配置文件解析: 1.1源码阅读入口: org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(); 功能:解析全局配置文 ...
- MyBatis源码分析(1)-MapConfig文件的解析
1.简述 MyBatis是一个优秀的轻ORM框架,由最初的iBatis演化而来,可以方便的完成sql语句的输入输出到java对象之间的相互映射,典型的MyBatis使用的方式如下: String re ...
- mybatis源码分析(三)------------映射文件的解析
本篇文章主要讲解映射文件的解析过程 Mapper映射文件有哪几种配置方式呢?看下面的代码: <!-- 映射文件 --> <mappers> <!-- 通过resource ...
- 【mybatis源码学习】mybtias基础组件-占位符解析器
一.占位符解析器源码 1.占位符解析器实现的目标 通过解析字符串中指定前后缀中的字符,并完成相应的功能. 在mybtias中的应用,主要是为了解析Mapper的xml中的sql语句#{}中的内容,识别 ...
- mybatis源码学习(三):MappedStatement的解析过程
我们之前介绍过MappedStatement表示的是XML中的一个SQL.类当中的很多字段都是SQL中对应的属性.我们先来了解一下这个类的属性: public final class MappedSt ...
- MyBatis 源码分析 - 映射文件解析过程
1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...
- MyBatis 源码分析 - 插件机制
1.简介 一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展.这样的好处是显而易见的,一是增加了框架的灵活性.二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作.以 My ...
- MyBatis 源码分析 - 缓存原理
1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...
- MyBatis 源码分析系列文章导读
1.本文速览 本篇文章是我为接下来的 MyBatis 源码分析系列文章写的一个导读文章.本篇文章从 MyBatis 是什么(what),为什么要使用(why),以及如何使用(how)等三个角度进行了说 ...
随机推荐
- C#多线程的用法10-线程池
TheadPool:在进行多线程编程时,如果不想频繁的创建线程,那可以考虑使用使用线程池来完成多线程编程的工作.你只需将要处理的任务交付给ThreadPool,如果ThreadPool中有空闲的线程, ...
- C# 倒计时
c#中有一个叫做timespan的数据类型,可以这样构造: TimeSpan ts = , , ); TimeSpan(hour,minute,second); 然后拖进去一个timer,叫timer ...
- Python学习--Selenium模块
1. Python学习--Selenium模块介绍(1) 2.Python学习--Selenium模块学习(2) 其他: 1. Python学习--打码平台
- bootstrap datepicker含有hasDatepicker无法弹出
bootstrap datepicker 初始化时,会给控件添加hasDatepicker类 ,如果此时调用 $singleDay.datepicker(initDayOpts);无法弹出时间控件 需 ...
- 洛谷P1208
#include <iostream>#include <algorithm>#include <cstdio>using namespace std; struc ...
- [SDOI2008]洞穴勘测
嘟嘟嘟 写完lct的板儿后觉得这就是一道大水题. 连pushup都不用. 不过还是因为一个zz的错误debug了一小会儿(Link的时候连出自环--) 还有一件事就是Cut的时候判断条件还得加上,因为 ...
- mysql主从复制亲测,以及注意事项
本人亲测,windows作为mysql主服务器,linux作为从服务器,使用两个linux配置步骤都一样,测一遍而已:区别配置文件在于windwos是my.ini.linux在/etc/my.cof ...
- App常见产品问题及预防方法
01界面适配 a:手机分辨率为1920x7080的高分辨率手机,在调整手机字体大小时,会导致页面显示出现变形: b:因用户设置的特殊字体导致列表的字母条不显示: c:某些banner 图片在部分机型只 ...
- Grunt-jsdoc生成JS API文档
Grunt-jsdoc生成JS API文档 具体的请看官网 https://github.com/krampstudio/grunt-jsdoc 一:首先确保本机电脑上是否已经安装了nodejs和np ...
- Python2.7-difflib
difflib主要用于比较两个序列的不同,常见于字符串的比较,可以对差异生成报告.SequenceMatcher 主要用于找两者相似部分,以及两者不同的转换方法,而 Differ 更注重于比较两者的区 ...