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
進行獲取和設定各個屬性, 再次就不過多的進行深入。