【深入理解MyBatis】- 05Mybatis 从0开始实现Mybatis XML解析功能

Mybatis XML技术简介

Mybatis使用XML解析技术为java的DOM技术

DOM 是 W3C 处理 XML 的标准 API,它是许多其它与 XML 处理相关的标准的基础,不仅是 Java,其它诸如 Javascript,PHP,MS .NET 等等语言都实现了该标准, 成为了应用最为广泛的 XML 处理方式。当然,为了能提供更多更加强大的功能,Java 对于 DOM 直接扩展工具类有很多,比如很多 Java 程序员耳熟能详的 JDOM,DOM4J 等等, 它们基本上属于对 DOM 接口功能的扩充,保留了很多 DOM API 的特性。

实现

下面给出一个运用 DOM 解析 XML 的例子:

import java.io.FileInputStream;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.apache.ibatis.builder.BuilderException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class XPathTest {
	public static void main(String[] args) throws Exception {
		
		XPathFactory pathFactory = XPathFactory.newInstance();
	    XPath xpath = pathFactory.newXPath();
		
		Document document = null;
		// 固定写法,不用追究
		try {
			InputStream inputStream = new FileInputStream("C:\\Users\\TEST\\Desktop\\DDL\\test.xml");
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			factory.setValidating(false);

			factory.setNamespaceAware(false);
			factory.setIgnoringComments(true);
			factory.setIgnoringElementContentWhitespace(false);
			factory.setCoalescing(false);
			factory.setExpandEntityReferences(true);

			DocumentBuilder builder = factory.newDocumentBuilder();
			builder.setEntityResolver(null);
			builder.setErrorHandler(new ErrorHandler() {
				@Override
				public void error(SAXParseException exception) throws SAXException {
					throw exception;
				}

				@Override
				public void fatalError(SAXParseException exception) throws SAXException {
					throw exception;
				}

				@Override
				public void warning(SAXParseException exception) throws SAXException {
				}
			});
			document = builder.parse(new InputSource(inputStream));
		} catch (Exception e) {
			throw new BuilderException("Error creating document instance.  Cause: " + e, e);
		}
		
		// 获取Double类型值
		System.out.println(document);
		Double doubleValue = (Double) xpath.evaluate("/employee/height", document, XPathConstants.NUMBER);
		// 获取String类型值
		System.out.println(doubleValue);
		String stringValue = (String) xpath.evaluate("/employee/@id", document, XPathConstants.STRING);
		System.out.println(stringValue);
		String stringValue2 = (String) xpath.evaluate("/employee/last_name", document, XPathConstants.STRING);
		// 获取结点Node类型
		System.out.println(stringValue2);
		Node node = (Node) xpath.evaluate("/employee/last_name", document, XPathConstants.NODE);
		System.out.println(node.toString());
		Node node2 = (Node) xpath.evaluate("/employee/@id", document, XPathConstants.NODE);
		System.out.println(node2.toString());
		// 获取多个结点NODESET类型
		NodeList nodes = (NodeList)xpath.evaluate("/employee/*", document, XPathConstants.NODESET);
		System.out.println(nodes.getLength());
		for (int i = 0; i < nodes.getLength(); i++) {
			Node item = nodes.item(i);
			System.out.println(item);
	    }
	}
}

测试文件C:\\Users\\TEST\\Desktop\\DDL\\test.xml

<employee id="${id_var}">
  <blah something="that"/>
  <first_name>Jim</first_name>
  <last_name>Smith</last_name>
  <birth_date>
    <year>1970</year>
    <month>6</month>
    <day>15</day>
  </birth_date>
  <height units="ft">5.8</height>
  <weight units="lbs">200</weight>
  <active>true</active>
</employee>

测试结果

[#document: null]
5.8
${id_var}
Smith
[last_name: null]
id="${id_var}"
7
[blah: null]
[first_name: null]
[last_name: null]
[birth_date: null]
[height: null]
[weight: null]
[active: null]

分析Mybatis XML应用

结合Mybatis的占位符替换,来看看Mybatis是如何读取XML并替换占位符的
对应源文件org.apache.ibatis.parsing.XPathParser#evalString

public String evalString(Object root, String expression) {
	// 读取xml属性
	String result = (String) evaluate(expression, root, XPathConstants.STRING);
	// 替换占位符
	result = PropertyParser.parse(result, variables);
	return result;
}

通过以上的了解,我们知道了Mybatis是如何读取XML,Mybatis XML解析也是上述实现的封装,实现类参考org.apache.ibatis.parsing.XPathParser

你可能感兴趣的:(深入理解MyBatis)