mybatis源码-解析配置文件(一)之XML的DOM解析方式

@node

简介

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

  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 步, 解析配置文件。github


Java 中 XML 文件解析

mybatis是基于 XML 来进行配置的, 所以, 咱们首先要知道在Java中, XML是如何解析的。sql

解析方式

XML 常见的解析方式有如下三种: DOMSAXStAX数据库

1. DOM 方式

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

2. SAX 方式

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

3. StAX 方式

StAXSAX 相似, 也是把 XML 文档做为一个事件流进行处理, 但不一样之处在于 StAX 采用的是“拉模式”, 即应用程序经过调用解析器推动解析的过程。dom


DOM 解析 XML

在加载 mybatis-config.xml 配置文件与映射文件时, 使用的是 DOM 解析方式, 并配合使用 XPath 解析 XML 配置文件。ide

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最新源码和注释

github项目

相关文章
相关标签/搜索