@

简介

在之前的文章《mybatis 初步使用(IDEA的Maven项目, 超详细)》中, 讲解了mybatis的初步使用, 并总结了以下mybatis的执行流程:

  1. 通过 Resources 工具类读取 mybatis-config.xml, 存入 Reader;
  2. SqlSessionFactoryBuilder使用上一步获得的reader创建SqlSessionFactory对象;
  3. 通过 sqlSessionFactory 对象获得SqlSession;
  4. SqlSession对象通过selectList方法找到对应的“selectAll”语句, 执行SQL查询。
  5. 底层通过 JDBC 查询后获得ResultSet, 对每一条记录, 根据resultMap的映射结果映射到Student中, 返回List。
  6. 最后记得关闭 SqlSession

本系列文章深入讲解第 2 步, 解析配置文件。


Java 中 XML 文件解析

mybatis是基于 XML 来进行配置的, 因此, 我们首先要知道在Java中, XML是如何解析的。

解析方式

XML 常见的解析方式有以下三种: DOMSAXStAX

1. DOM 方式

DOM 基于树形结构解析, 它会将整个文档读入内存并构建一个 DOM 树, 基于这棵树的结构对各个节点进行解析。

2. SAX 方式

SAX 是基于事件模型的 XML 解析方式, 它不需要将整个 XML 文档加载到内存中, 而只需要将一部分 XML 文档的一部分加载到内存中, 即可开始解析。

3. StAX 方式

StAXSAX 类似, 也是把 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中, 有很多CDCD有着自己的子节点。

DOM 操作相关类

以上的XML, 其对应的树形结构如下:

而在Java中, 有很节点类型, 以下有几个主要的接口对应着XML中的各个属性。

  1. Node : DOM最基本的数据类型。 表示文档树中的单个节点
  2. Element:常见的元素节点
  3. Attr:代表元素的属性
  4. Text:元素或者Att的值(内容)
  5. 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());
}
}

其主要步骤:

  1. 创建 DocumentBuilderFactory 对象;
  2. 通过 DocumentBuilderFactory 创建DocumentBuilder对象;
  3. 通过DocumentBuilder, 从文件或流中创建通过Document对象;
  4. 创建XPathFactory对象, 并通过XPathFactory创建XPath对象;
  5. 通过XPath解析出XPathExpression对象;
  6. 使用XPathExpression在文档中搜索出相应的节点。

输出结果如下:

也可以调用相应的 API 进行获取和设置各个属性, 在此就不过多的进行深入。

一起学 mybatis

你想不想来学习 mybatis? 学习其使用和源码呢?那么, 在博客园关注我吧!!

我自己打算把这个源码系列更新完毕, 同时会更新相应的注释。快去 star 吧!!

mybatis最新源码和注释

mybatis源码-解析配置文件(一)之XML的DOM解析方式的更多相关文章

  1. MyBatis 源码分析 - 配置文件解析过程

    * 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...

  2. Mybatis源码阅读-配置文件及映射文件解析

    Mybatis源码分析: 1.配置文件解析: 1.1源码阅读入口: org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(); 功能:解析全局配置文 ...

  3. MyBatis源码分析(1)-MapConfig文件的解析

    1.简述 MyBatis是一个优秀的轻ORM框架,由最初的iBatis演化而来,可以方便的完成sql语句的输入输出到java对象之间的相互映射,典型的MyBatis使用的方式如下: String re ...

  4. mybatis源码分析(三)------------映射文件的解析

    本篇文章主要讲解映射文件的解析过程 Mapper映射文件有哪几种配置方式呢?看下面的代码: <!-- 映射文件 --> <mappers> <!-- 通过resource ...

  5. 【mybatis源码学习】mybtias基础组件-占位符解析器

    一.占位符解析器源码 1.占位符解析器实现的目标 通过解析字符串中指定前后缀中的字符,并完成相应的功能. 在mybtias中的应用,主要是为了解析Mapper的xml中的sql语句#{}中的内容,识别 ...

  6. mybatis源码学习(三):MappedStatement的解析过程

    我们之前介绍过MappedStatement表示的是XML中的一个SQL.类当中的很多字段都是SQL中对应的属性.我们先来了解一下这个类的属性: public final class MappedSt ...

  7. MyBatis 源码分析 - 映射文件解析过程

    1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...

  8. MyBatis 源码分析 - 插件机制

    1.简介 一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展.这样的好处是显而易见的,一是增加了框架的灵活性.二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作.以 My ...

  9. MyBatis 源码分析 - 缓存原理

    1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...

  10. MyBatis 源码分析系列文章导读

    1.本文速览 本篇文章是我为接下来的 MyBatis 源码分析系列文章写的一个导读文章.本篇文章从 MyBatis 是什么(what),为什么要使用(why),以及如何使用(how)等三个角度进行了说 ...

随机推荐

  1. Linux网络配置和网络诊断命令介绍

    方法/步骤 1 在接下来的讲解中,讲解的Linux网络配置和网络诊断的命令有: ifconfig.ping.netstat.traceroute.dig和nslookup.host.hostname. ...

  2. 使用 PowerShell 将数据磁盘附加到 Windows VM

    本文介绍如何使用 PowerShell 将新磁盘和现有磁盘附加到 Windows 虚拟机. 在开始之前,请查看以下提示: 虚拟机的大小决定了可以附加多少个磁盘. 有关详细信息,请参阅虚拟机大小. 若要 ...

  3. .net 页面传参方式总结

    一.使用Querystring Querystring是一种非常简单的传值方式,其缺点就是:安全性低.会把要传送的值显示在浏览器的地址栏中(也就是不需要保密得参数),并且在此方法中不能够传递对象,参数 ...

  4. wc 命令使用说明

    wc 命令 使用说明 wc 命令还是很是简单的,通过 man 命令,可以见到可以选择的选项: wc option file 并且 wc 命令支持 管道操作 其中较为常用的命令选项 -c 字符的个数 - ...

  5. Docker容器学习与分享08

    Docker容器网络 Docker除了默认创建的三种网络外,还可以自定义网络. 首先创建一个bridge类型的网络,使用docker network create命令. [root@promote ~ ...

  6. 实现统计 android手机 CPU使用率

    # -*- coding:utf-8 -*- ''' Created on Sep 10, 2018 @author: SaShuangYiBing ''' import subprocess imp ...

  7. HTML标签之marquee

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/zkn_CS_DN_2013/article/details/25229719 <html> ...

  8. 如何为已有的类没有生成toString的方法增强生成toString方法

    1:只要提到增强,我的第一思路就是代理,动态代理.但是仅仅是一个toString其实没必要使用代理模式了,有点大材小用了(动态代理其实也是最后通过反射生成toString的方法). 2:简单粗暴,可以 ...

  9. php请求API接口方法

    thinkphp下直接放入公共函数即可. /** * 通过URL获取页面信息 * @param string $url 地址 * @return string 返回页面信息 */ function g ...

  10. linux 的常用命令---------第四阶段

    权限管理 “4” “r” → 读权限: 查看文件内容: 是否能够列出目录结构. “2” “w” → 写权限: 编辑文件内容: 是否能够创建.删除.复制.移动目录. “1” “x” → 执行权限: 对二 ...