@
簡介
在之前的文章《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 吧!!

