@node
在以前的文章《mybatis 初步使用(IDEA的Maven項目, 超詳細)》中, 講解了mybatis
的初步使用, 並總結了如下mybatis
的執行流程:git
- 經過 Resources 工具類讀取 mybatis-config.xml, 存入 Reader;
- SqlSessionFactoryBuilder使用上一步得到的reader建立SqlSessionFactory對象;
- 經過 sqlSessionFactory 對象得到SqlSession;
- SqlSession對象經過selectList方法找到對應的「selectAll」語句, 執行SQL查詢。
- 底層經過 JDBC 查詢後得到ResultSet, 對每一條記錄, 根據resultMap的映射結果映射到Student中, 返回List。
- 最後記得關閉 SqlSession
本系列文章深刻講解第 2 步, 解析配置文件。github
mybatis
是基於 XML
來進行配置的, 所以, 咱們首先要知道在Java
中, XML
是如何解析的。sql
XML
常見的解析方式有如下三種: DOM
、 SAX
和 StAX
。數據庫
DOM
基於樹形結構解析, 它會將整個文檔讀入內存並構建一個 DOM
樹, 基於這棵樹的結構對各個節點進行解析。express
SAX
是基於事件模型的 XML
解析方式, 它不須要將整個 XML
文檔加載到內存中, 而只須要將一部分 XML
文檔的一部分加載到內存中, 便可開始解析。mybatis
StAX
與 SAX
相似, 也是把 XML
文檔做爲一個事件流進行處理, 但不一樣之處在於 StAX
採用的是「拉模式」, 即應用程序經過調用解析器推動解析的過程。dom
在加載 mybatis-config.xml
配置文件與映射文件時, 使用的是 DOM
解析方式, 並配合使用 XPath
解析 XML
配置文件。ide
XPath
之於 XML
就比如 SQL
之於數據庫。
所謂DOM
, 是 Document Object Model 的縮寫, 翻譯過來就是文檔對象模型。
下面咱們就來展現一下該過程。
<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
有着本身的子節點。
以上的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? 學習其使用和源碼呢?那麼, 在博客園關注我吧!!
我本身打算把這個源碼系列更新完畢, 同時會更新相應的註釋。快去 star 吧!!