Mybatis中mapper的xml解析詳解

上一篇文章分析了mapper注解關(guān)鍵類MapperAnnotationBuilder,今天來(lái)看mapper的項(xiàng)目了解析關(guān)鍵類XMLMapperBuilder。

?

基礎(chǔ)介紹

回顧下之前是在分析configuration的初始化過(guò)程,已經(jīng)進(jìn)行到了最后一步mapperElement(root.evalNode("mappers")),這個(gè)方法里有兩種解析mapper的方法,一種是解析類,一種是解析xml文件,上一篇文章在講解析類中的注解,今天說(shuō)到的就是解析xml的流程,關(guān)鍵代碼如下:


解析mapper有4種情況可以分成根據(jù)類解析和根據(jù)xml文件解析兩類,這次是后面這類,主體方法還是比較簡(jiǎn)單。

首先根據(jù)inputStream, configuration, resource或url, configuration.getSqlFragments()四個(gè)參數(shù)初始化一個(gè)XMLMapperBuilder;

然后執(zhí)行XMLMapperBuilder對(duì)象的parse方法;

初始化XMLMapperBuilder

初始化過(guò)程源碼已在上圖的右側(cè)部分,初始化XMLMapperBuilder方法的流程與加載mybatis的配置文件關(guān)鍵類XMLConfigBuilder及其相似,都是通過(guò)xml文件創(chuàng)建XPathParser對(duì)象作為XMLMapperBuilder對(duì)象的parse屬性。最后執(zhí)行parse方法去解析xml文件內(nèi)容。

實(shí)際上XMLMapperBuilder與XMLConfigBuilder都繼承BaseBuilder類,通過(guò)名字也可以看出來(lái)他們采用的是構(gòu)建者模式,在結(jié)合他們的使用流程就能夠更加理解mybatis采用構(gòu)建者模式對(duì)不同的xml解析過(guò)程。


在初始化方法中又出現(xiàn)了一個(gè)關(guān)鍵類MapperBuilderAssistant,這個(gè)在上一篇分析MapperAnnotationBuilder類是發(fā)現(xiàn)MapperAnnotationBuilder解析了所有的注解然后把解析的內(nèi)容給到MapperBuilderAssistant對(duì)象,然后通過(guò)MapperBuilderAssistant對(duì)象生成的對(duì)象具體sql的MappedStatement對(duì)象。

這里可以大膽猜測(cè)XMLMapperBuilder應(yīng)該也是一樣,解析出xml中所有信息然后給到MapperBuilderAssistant去生產(chǎn)MappedStatement對(duì)象。

XMLMapperBuilder和MapperAnnotationBuilder都是工具人,MapperBuilderAssistant才是真正生成MappedStatement對(duì)象的類

parse方法

parse方法比較簡(jiǎn)單在上圖中也已經(jīng)把源碼貼出來(lái)了,主要分四步:驗(yàn)證重復(fù)加載、加載mapper節(jié)點(diǎn)并解析、綁定名稱空間、解決未處理的方法。

第一三步比較簡(jiǎn)單就不在詳細(xì)說(shuō)了,而第四步是也就是parse方法最后三行代碼,他的主要作用是解決在第二步解析mapper時(shí)不能處理的一些數(shù)據(jù)進(jìn)行處理,代碼比較簡(jiǎn)單不在詳細(xì)分析了,源碼如下:


configurationElement方法

可以看出來(lái)最最關(guān)鍵的方法還是parse方法的configurationElement方法,他才是真正解析mapper.xml的方法,方法源碼如下圖:


方法比較簡(jiǎn)單,就是讀取對(duì)應(yīng)節(jié)點(diǎn)的數(shù)據(jù),進(jìn)行解析,重點(diǎn)是調(diào)用的這些解析方法,可以看到一些我們平時(shí)最常見(jiàn)的比如mapper節(jié)點(diǎn)上的namespace屬性,還有常見(jiàn)的resultMap節(jié)點(diǎn)、sql節(jié)點(diǎn)等。

這里我簡(jiǎn)單點(diǎn)就只看最后一行解析具體的select|insert|update|delete節(jié)點(diǎn)的方法,因?yàn)樗麄儗?duì)應(yīng)的就是我們具體的sql了。根據(jù)上圖可以看到獲取所有的這類節(jié)點(diǎn),然后遍歷生成了一個(gè)XMLStatementBuilder的對(duì)象并執(zhí)行parseStatementNode方法。接下來(lái)來(lái)看XMLStatementBuilder類。

XMLStatementBuilder類

XMLStatementBuilder的源碼如下圖:


XMLStatementBuilder與XMLMapperBuilder一樣都是繼承BaseBuilder類,它的XNode類型屬性context對(duì)應(yīng)mapper文件中一個(gè)select、update等節(jié)點(diǎn)。初始化方法沒(méi)什么說(shuō)的,主要看parseStatementNode方法,上圖中已經(jīng)截圖一部分,剩下部分如下圖:


parseStatementNode方法并不復(fù)雜,都是在讀取context的數(shù)據(jù),主要是最后圈出來(lái)的代碼,和上一篇解析MapperAnnotationBuilder類最后調(diào)用的是同一方法。

前面猜錯(cuò)了啊,XMLMapperBuilder連工具人都算不上,XMLStatementBuilder才算生成MappedStatement的工具人。不過(guò)仔細(xì)一想也是對(duì)的,XMLMapperBuilder對(duì)應(yīng)的是一個(gè)mapper.xml文件,而要生成的MappedStatement對(duì)應(yīng)的是具體的一條CRUD語(yǔ)句,一個(gè)xml是包含多條CRUD語(yǔ)句的。

總結(jié)

一個(gè)XMLMapperBuilder對(duì)應(yīng)一個(gè)mapper.xml文件,而XMLMapperBuilder能夠從xml文件中獲取多個(gè)CRUD語(yǔ)句對(duì)應(yīng)的節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)對(duì)應(yīng)生成一個(gè)XMLStatementBuilder對(duì)象,XMLStatementBuilder解析節(jié)點(diǎn)中所有信息后與MapperAnnotationBuilder解析出注解中包含的信息一樣交給MapperBuilderAssistant去生成一個(gè)MappedStatement。


Java程序員日常學(xué)習(xí)筆記,如理解有誤歡迎各位交流討論!


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容