解析xml_Mybatis中mapper的xml解析詳解

上一篇文章分析了mapper注解關鍵類MapperAnnotationBuilder,今天來看mapper的項目了解析關鍵類XMLMapperBuilder。

基礎介紹

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

16edb869994cc9f60ce3205b55083fbf.png

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

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

然后執行XMLMapperBuilder對象的parse方法;

初始化XMLMapperBuilder

初始化過程源碼已在上圖的右側部分,初始化XMLMapperBuilder方法的流程與加載mybatis的配置文件關鍵類XMLConfigBuilder及其相似,都是通過xml文件創建XPathParser對象作為XMLMapperBuilder對象的parse屬性。最后執行parse方法去解析xml文件內容。

實際上XMLMapperBuilder與XMLConfigBuilder都繼承BaseBuilder類,通過名字也可以看出來他們采用的是構建者模式,在結合他們的使用流程就能夠更加理解mybatis采用構建者模式對不同的xml解析過程

在初始化方法中又出現了一個關鍵類MapperBuilderAssistant,這個在上一篇分析MapperAnnotationBuilder類是發現MapperAnnotationBuilder解析了所有的注解然后把解析的內容給到MapperBuilderAssistant對象,然后通過MapperBuilderAssistant對象生成的對象具體sql的MappedStatement對象。

這里可以大膽猜測XMLMapperBuilder應該也是一樣,解析出xml中所有信息然后給到MapperBuilderAssistant去生產MappedStatement對象

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

parse方法

parse方法比較簡單在上圖中也已經把源碼貼出來了,主要分四步:驗證重復加載、加載mapper節點并解析、綁定名稱空間、解決未處理的方法。

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

851c672a8a1bd1b27c4b2375f1be437b.png

configurationElement方法

可以看出來最最關鍵的方法還是parse方法的configurationElement方法,他才是真正解析mapper.xml的方法,方法源碼如下圖:

8d33aea4072cc5c5e46b4c51be24abf5.png

方法比較簡單,就是讀取對應節點的數據,進行解析,重點是調用的這些解析方法,可以看到一些我們平時最常見的比如mapper節點上的namespace屬性,還有常見的resultMap節點、sql節點等。

這里我簡單點就只看最后一行解析具體的select|insert|update|delete節點的方法,因為他們對應的就是我們具體的sql了。根據上圖可以看到獲取所有的這類節點,然后遍歷生成了一個XMLStatementBuilder的對象并執行parseStatementNode方法。接下來來看XMLStatementBuilder類。

XMLStatementBuilder

XMLStatementBuilder的源碼如下圖:

14275c296a5577182a5bbbeb2b9f1c17.png

XMLStatementBuilder與XMLMapperBuilder一樣都是繼承BaseBuilder類,它的XNode類型屬性context對應mapper文件中一個select、update等節點。初始化方法沒什么說的,主要看parseStatementNode方法,上圖中已經截圖一部分,剩下部分如下圖:

16fd5c0f3881e35ba5552fdc20d8d60a.png

parseStatementNode方法并不復雜,都是在讀取context的數據,主要是最后圈出來的代碼,和上一篇解析MapperAnnotationBuilder類最后調用的是同一方法。

前面猜錯了啊,XMLMapperBuilder連工具人都算不上,XMLStatementBuilder才算生成MappedStatement的工具人。不過仔細一想也是對的,XMLMapperBuilder對應的是一個mapper.xml文件,而要生成的MappedStatement對應的是具體的一條CRUD語句,一個xml是包含多條CRUD語句的。

總結

一個XMLMapperBuilder對應一個mapper.xml文件,而XMLMapperBuilder能夠從xml文件中獲取多個CRUD語句對應的節點,每個節點對應生成一個XMLStatementBuilder對象,XMLStatementBuilder解析節點中所有信息后與MapperAnnotationBuilder解析出注解中包含的信息一樣交給MapperBuilderAssistant去生成一個MappedStatement。

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

0934d3e3cc8ab544eb53991317324ad0.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/542041.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/542041.shtml
英文地址,請注明出處:http://en.pswp.cn/news/542041.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

lnmp—MemCache的作用

含義及理解: 1 . memcache是一個高性能的分布式的內存對象緩存系統,用于動態web應用以減輕數據庫負擔。通過在內存里維護一個統一的巨大的hash表,來存儲經常被讀寫的一些數組與文件,從而極大的提高網站的運行效率。 memcache是一…

Java ListResourceBundle getKeys()方法與示例

ListResourceBundle類的getContents()方法 (ListResourceBundle Class getContents() method) getContents() method is available in java.util package. getContents()方法在java.util包中可用。 getContents() method is used to return an enumeration of all the keys tha…

orale用戶密碼過期處理

使用具有管理權限的用戶登錄1、查看用戶的proifle是哪個,一般是default:SELECT username,PROFILE FROM dba_users;2、查看指定概要文件(如default)的密碼有效期設置:sql>SELECT * FROM dba_profiles s WHERE s.prof…

python字典怎么設置_在python中設置字典中的屬性

在python中設置字典中的屬性是否可以在python中從字典創建一個對象,使每個鍵都是該對象的屬性?像這樣的東西:d { name: Oscar, lastName: Reyes, age:32 }e Employee(d)print e.name # Oscarprint e.age 10 # 42我認為這幾乎與這個問題相反…

Java ObjectInputStream readByte()方法與示例

ObjectInputStream類readByte()方法 (ObjectInputStream Class readByte() method) readByte() method is available in java.io package. readByte()方法在java.io包中可用。 readByte() method is used to read a byte (i.e. 8 bit) of data from this ObjectInputStream. re…

openresty—實現緩存前移

含義及理解: OpenResty(又稱:ngx_openresty) 是一個基于 NGINX 的可伸縮的 Web 平臺,由中國人章亦春發起,提供了很多高質量的第三方模塊。 其目標是讓Web服務直接跑在Nginx服務內部,充分利用Nginx的非阻塞I/O模型&am…

Nginx+Keepalived+Tomcat之動靜分離的web集群

NginxKeepalivedTomcat之動靜分離的web集群 博客分類: webserverNginxKeepalivedTomcat之動靜分離的web集群為小公司提供大概一天持續在100萬/日之間訪問的高性能、高可用、高并發訪問及動靜分離的web集群方案NginxKeepalived 高可用、反向代理NginxPHP …

安裝完成后的配置_cent os7 默認安裝后的一般配置

在安裝cent os7后,進入系統會出現一些命令無法執行。這是因為最小化沒有安裝包含的軟件包。這時候先要配置一下基本的IP參數,(包括動態,靜態,或者是雙網卡綁定)。我們在虛擬機中模擬操作一下,配置文件在/etc/sysconfig…

Java Integer類lowerOneBit()方法與示例

整數類lowerOneBit()方法 (Integer class lowestOneBit() method) lowestOneBit() method is available in java.lang package. minimumOneBit()方法在java.lang包中可用。 lowestOneBit() method is used to find at most only single 1’s bit from the rightmost side one b…

lnmp構架——對tomcat詳解

tomcat的安裝部署 安裝jdk和tomcat tar zxf jdk-7u79-linux-x64.tar.gz -C /usr/local/ tar zxf apache-tomcat-7.0.37.tar.gz -C /usr/local/做好軟連接便于訪問 cd /usr/local ln -s jdk1.7.0_79/ java ln -s apache-tomcat-7.0.37/ tomcat配置環境變量 vim /etc/profile…

Linux 查找文件

find 查找目錄 -name "文件名"find / -name "php.ini"locate 文件名locate php.ini 一:locate命令 locate命令用于查找文件,它比find命令的搜索速度快,它需要一個數據庫,這個數據庫由每天的例行工作&#xff…

Java GregorianCalendar hashCode()方法與示例

GregorianCalendar類的hashCode()方法 (GregorianCalendar Class hashCode() method) hashCode() method is available in java.util package. hashCode()方法在java.util包中可用。 hashCode() method is used to returns the hash code for this GregorianCalendar. hashCode…

python元組為什么不可變_為什么python字符串和元組是不可變的?

我不知道為什么字符串和元組是不可變的;使它們不可變的優點和缺點是什么?除了Python解釋器的內部實現,這種設計在編寫程序上是否有很好的意義?(例如,如果元組和字符串是可變的,會更容易嗎?)如果…

InnoDB事務結構體代碼變量列表

事務結構 struct trx_t 寫在前面 InnoDB是MySQL的一個存儲引擎,支持事務,支持非堵塞的一致性讀,物理存儲結構是Page,每個事務都有回滾日志,重做日志,事務還會有死鎖檢測,各種各樣不同的鎖等等等…

對cookie與session的理解

cookie: 在網站中,http請求是無狀態的。也就是說即使第一次和服務器連接后并且登錄成功后,第二次請求服務器依然不能知道當前請求是哪個用戶。 cookie的出現就是為了解決這個問題, 第一次登錄后服務器返回一些數據(…

ubutun 更換網絡源_Ubuntu 更換源

1.切換到root用戶# su root備份源文件 目錄:/etc/apt# cd /etc/apt/# cp sources.list sources.list.bk3.更換源 阿里源 清華源# >sources.list # 清空源# vim sources.list # 選擇一個源,復制進去# apt update # 更新源,需要等幾分鐘# ex…

php : 常用函數

常用函數&#xff1a; <?php /*** 獲取客戶端IP* return [string] [description]*/ function getClientIp() {$ip NULL;if (isset($_SERVER[HTTP_X_FORWARDED_FOR])) {$arr explode(,, $_SERVER[HTTP_X_FORWARDED_FOR]);$pos array_search(unknown,$arr);if(false ! $po…

java日歷類add方法_Java日歷setFirstDayOfWeek()方法與示例

java日歷類add方法日歷類setFirstDayOfWeek()方法 (Calendar Class setFirstDayOfWeek() method) setFirstDayOfWeek() method is available in java.util package. setFirstDayOfWeek()方法在java.util包中可用。 setFirstDayOfWeek() method is used to sets the first day o…

zabbix監控部署 與添加主機

zabbix介紹&#xff1a; zabbix&#xff08;[zbiks]&#xff09;是一個基于WEB界面的提供分布式系統監視以及網絡監視功能的企業級的開源解決方案。zabbix能監視各種網絡參數&#xff0c;保證服務器系統的安全運營&#xff1b;并提供靈活的通知機制以讓系統管理員快速定位/解決…

線段樹 洛谷 p1531 I hate it(I hate it too)

這里寫鏈接內容 線段樹模板 字符串是一個很詭異的問題。。。。 #include<cstdio> #include<iostream> #include<string> #define q 200000 using namespace std; int a[q5],s[q<<25]; void bu(int o,int l,int r)//建樹 {if(lr){s[o]a[r];} else{int…