MyBatis映射文件&動態SQL回顧和拓展_TCF

MyBatis映射文件&動態SQL回顧和拓展

                                                                                   20190620 田超凡

  知網用戶_進擊的猿寶寶(田超凡)爲本文作者,如需轉載請註明原作者

 

  1. MyBatis映射文件

  (1).關於映射文件的一些必要條件和約束:

   一、映射文件是必要的。

映射文件存在的目的就是可以建立ORM映射關係,在程序中以OOP的方式來執行映射文件中預先定義的對應的SQL語句來實現對數據庫的CRUD操作。因此,映射文件是MyBatis必不可少的一部分,沒有映射文件的MyBatis也就沒有實際存在的意義,因爲持久層框架存在的目的就是簡化程序對數據庫的持久化操作,不要映射文件的話爲什麼不選用傳統的JDBC呢?很明晰弊端很多比如SQL注入拼接麻煩等等問題。因此,映射文件在MyBatis中的地位及其重要。

 

二、每一個映射文件必須和一個持久層接口關聯。

需要在映射文件的根元素mappernamespace指定。原因很容易理解,在一個大型軟件系統中,數據庫的表是非常多的,對應的POJO肯定也是非常多的,每一個POJO一般情況下都對應一個持久層接口和一個映射文件,如果持久層接口沒有和映射文件進行關聯,則映射文件也就沒有了依賴的源,或者說不知道需要執行哪些SQL,而映射文件和持久層接口進行11關聯之後,映射文件的職責就變得更加單一和清晰了,作爲映射文件而言,他只需要關注他關聯的持久層接口中有哪些持久化操作方法,然後編寫對應的SQL語句和這些方法關聯即可。當關聯的持久層接口方法發生變動(包括方法名、返回值、參數)時,映射文件中的方法也需要進行相應調整來適配這些關聯的接口中的方法。因此,每一個映射文件必須要通過頂級元素mappernamespace屬性顯示指定關聯的映射接口,這個是必要條件。

 

三、每一個映射文件中的SQL語句必須和關聯的持久層接口中的方法保持一一對應關係。

映射文件和持久層接口進行11關聯後,映射文件也需要和持久層接口中的方法數量保持一致,包括映射的方法名稱(通過映射文件元素的id屬性指定),入參類型(parameterType)和返回值類型(resultType/resultMap)。否則一旦持久層接口中的方法數量很多,和映射文件中每個方法對應的大量SQL語句匹配困難度會提升,並且容易出錯。

 

  四、關於映射文件的命名規則一定要遵循

MyBatis中的映射文件一般以xml格式存放在三層架構的持久層,傳統和習慣上我們對於這些映射文件的命名也是需要遵循一定規則的,大多數情況下習慣以POJO+Mapper的方式來命名,統一這樣命名的優點就體現在當一個成熟完善的軟件系統將持久層和業務層以及控制層進行整合時,尤其是Spring整合MyBatis時,可以基於映射文件的命名規則使用通配符一下掃描到所有的映射文件和持久層接口,所以一般建議遵循這個映射文件命名規範。

 

  1.1 resultMap 關聯映射

     ORM指的是對象-關係映射,當作用於MyBatis,ORM主要目的是將關係型數據庫中的表和後臺程序中的持久類(POJO,指持久層的普通成員類)建立映射關聯,使得數據庫中的表和持久類進行關聯,表的字段和持久類的屬性關聯。但是如何自定義一些規則來快速高效匹配表中的字段和POJO的屬性呢?MyBatis作爲一款基於ORM的持久層框架,自然爲我們考慮到了這個問題,那就是在Mapper映射文件中進行自定義映射關係,即resultMap元素來建立表字段和持久類屬性之間的映射關係。指定resultMap建立映射關係之後,就可以在映射文件其他需要返回查詢結果的地方直接通過resultMap屬性來引用這個預先定義好的映射結果集,resultMap元素中的子元素一般以<result property column/>爲主。

 

  1.2使用association實現一對一關聯映射

   associationresultMap元素的一個子元素,其存在的意義主要是當POJO中的屬性是另一個POJO引用時,可以通過association元素來顯示映射關聯的這個POJO,但是需要顯示指定association元素的javaType\column屬性,分別指的是映射的目標POJO的類型和外鍵關聯字段名。

 

  1.3使用collection實現一對多關聯映射

  collection元素也是resultMap的一個子元素,collection元素主要適用於當需要映射的POJO中包含集合類型的屬性時,可以通過配置自動進行1:N關聯映射填充這些集合元素的屬性。同樣需要顯示指定collection元素的ofType/column屬性來定義需要映射的目標集合元素類型和關聯字段,根據定義的規則自動映射關聯的集合元素。

 

  1.4 MyBatis緩存和延遲加載

  MyBatis針對DQL查詢語句提供了緩存和延遲加載機制,默認是沒有開啓二級緩存和延遲加載的,默認只開啓了一級緩存。一級緩存可以在MyBatis配置文件中配置全局元素來指定,一級緩存緩存的是全局查詢語句,也就是對整個持久層映射體系中的查詢語句有效。二級緩存指的是局部查詢語句,指可以針對一個或者部分映射文件中的一個或多個SQL查詢語句開啓,二級緩存需要在需要開啓的SQL元素上通過cacheEnabled屬性開啓。

需要注意的是:MyBatis一級緩存和二級緩存主要是優化多次執行相同查詢語句時的查詢性能問題,對於增刪改操作是無效的。同時如果在多個查詢語句和增刪改語句同時操作的情況下,每次執行增刪改語句都會清空緩存,但是如果同時執行多個查詢語句時,只要配置了開啓緩存,都是會採用配置的MyBatis緩存機制的。

  1. 常用的動態SQL元素

  2.1 if 基本判斷

if元素主要運用在SQL查詢語句的條件子句中,大多數情況的主要作用是直接進行邏輯判斷來拼接查詢條件

 

  2.2 if+set 邏輯判斷和更新

set元素主要用於UPDATE語句,替換SET關鍵字實現相同效果,並可以根據if元素的判斷條件進行需要更新的字段和更新值進行自動匹配,動態實現UPDATE操作。

 

  2.3 if+where 條件自適應邏輯判斷

where元素主要可以替代查詢SQL語句的WHERE關鍵字,特點在於使用where元素可以自動根據條件的數量和多少動態插入WHERE或者刪除WHERE,在沒有條件的時候自動剔除WHERE關鍵字,在有條件的時候自動加上WHERE關鍵字,實現SQL查詢語句的動態化,提高多參數多條件查詢的靈活性。


  2.4 if+trim 條件綴式過濾

trim元素主要是可以對SQL語句中動態拼接的多餘的前綴和後綴進行忽略或接入處理,prefix屬性指定需要自動加上的前綴,suffix屬性指定需要自動加上的後綴,prefixOverrides屬性指定需要自動忽略的多餘前綴,suffixOverrieds屬性指定需要自動忽略的多餘後綴。

  2.5 choose+when+otherwise 多重並列分支

choose+when+otherwise主要適用於統一列舉值的多重分支情況,類似後臺邏輯結構switch-case,主要目的是進行多重並列分支的條件判斷,簡化大量的if元素。

 

  2.6 foreach 元素迭代

foreach元素可以迭代一個數組或集合參數,主要應用場景是在提供的多個列舉值中檢索匹配結果,如IN /NOT IN子查詢語句,foreach元素可以通過collection指定需要遍歷的集合參數,item指定每次迭代的對象名稱,open指定循環開始前需要加上的前綴,separator指定每次循環結束後需要加上的分隔符,close指定整個循環結束後需要加上的後綴。

 

2.7 sql語句複用和入參

當需要在同一個映射文件多個SQL語句中複用同一段SQL,此時可以把這段需要複用的SQL單獨提出來放置在sql元素中,其他需要引用這段SQL語句的地方直接使用include refid指定需要複用的sql,一定程度上減少了複雜業務編寫的SQL語句的複雜程度。

對於MyBatis映射文件參數入參,可以使用#{參數名}或者${參數名}的方式。

#{參數名}是直接將參數解析爲普通字符串動態拼接到SQL語句中,參數是動態拼接的,因此整個SQL的執行過程是安全的。

${參數名}是將參數作爲一個變量拼接到SQL語句中,靈活方便,但是可能存在部分SQL注入風險,不能保證SQL執行過程是完全安全的,因爲有可能在SQL執行過程中這個變量的值發生更改,就會產生風險。雖然概率很小,但是一般不建議使用此種方式入參,除非該參數對整個SQL語句執行過程影響不大,比如動態指定排序規則等,此時爲了確保靈活性可以使用此種方式入參。但是如果涉及到敏感字段則不建議使用這種方式入參。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章