當前位置:
首頁 > 最新 > 深入淺出MyBatis:「映射器」全了解

深入淺出MyBatis:「映射器」全了解

本篇文章是「深入淺出MyBatis:技術原理與實踐」書籍的總結筆記。

上一篇總結了MyBatis的配置,詳細說明了各個配置項,其中提到了映射器,它是MyBatis最強大的工具,也是使用最多的工具。

通過映射器,可以很容易的進行數據的增刪改查操作,我們抽象下進行這些操作的關鍵點:傳遞查詢參數、組裝各種場景下的查詢條件、關聯查詢、將查詢結果映射為Java Bean對象或集合等。另外,可以通過延遲載入、緩存提高數據查詢的性能。

本篇就按照這個思路進行總結,首先列舉下映射器的主要元素,每個元素提供的配置項和作用,然後重點介紹參數、結果映射、延遲載入、緩存、動態SQL等功能。

映射器的主要元素

映射器是由Java介面和XML文件(或註解)共同組成的,Java介面主要定義調用者介面,XML文件是配置映射器的核心文件,包括以下元素:

select 查詢語句,可以自定義參數,返回結果集;

insert 插入語句,返回一個整數,表示插入的條數;

update 更新語句,返回一個整數,表示更新的條數;

delete 刪除語句,返回一個整數,表示刪除的條數;

sql 允許定義一部分SQL,然後再各個地方引用;

resultMap 用來描述從資料庫結果集中來載入對象,還可以配置關聯關係;

cache 給定命名空間的緩存配置;

增、刪、改、查操作

查找

執行select語句前,需要定義參數,執行後,也提供了強大的映射規則或自動映射,將返回的結果集綁定到java bean中。

select元素有很多配置項,下面簡單說明下:

paramterType:傳入的參數類型,可以是基本類型、map、自定義的java bean;

resultType:返回的結果類型,可以是基本類型、自定義的java bean;

resultMap:它是最複雜的元素,可以配置映射規則、級聯、typeHandler等,與ResultType不能同時存在;

flushCache:在調用SQL後,是否要求清空之前查詢的本地緩存和二級緩存,主要用於更新緩存,默認為false;

useCache:啟動二級緩存的開關,默認只會啟動一級緩存;

timeout:設置超時參數,等超時的時候將拋出異常,單位為秒;

fetchSize:獲取記錄的總條數設定;

比如根據米聊號獲取用戶信息:

上一篇介紹配置時,有個設置項autoMappingBehavior,默認為自動映射沒有定義嵌套結果集映射的結果集;還有設置項mapUnderscoreToCamelCase,設置為true時,會自動將以「下劃線」命名的資料庫欄位名,自動映射為以「駝峰式」命名的POJO。

傳遞多個參數時,有3種方式:

使用Map參數;

使用註解方式傳遞;

使用java bean;

使用註解方式如下:

使用Map傳遞參數,會導致業務可讀性喪失,導致以後擴展和維護不方便,不建議;如果參數個數5,建議使用JavaBean方式;

使用resultMap映射結果集,後面會單獨介紹。

insert

屬性和select大部分都相同, 說下3個不同的屬性:

keyProperty:指定哪個列是主鍵,如果是聯合主鍵可以用逗號隔開;

keyColumn:指定第幾列是主鍵,不能和keyProperty共用;

useGeneratedKeys:是否使用自動增長,默認為false;

當useGeneratedKeys設為true時,在插入的時候,會回填Java Bean的id值,通過返回的對象可獲取主鍵值。

如果想根據一些特殊關係設置主鍵的值,可以在insert標籤內使用selectKey標籤,比如:如果t_role沒有記錄,則需要設置為1,否則取最大id加2:

update和delete

比較簡單,就不過多介紹了。

參數

上面已經介紹了參數傳遞,另外可以指定參數的類型去讓對應的typeHandler處理它們。

還可以對一些數值型的參數設置其保存的精度

一般都是傳遞字元串,設置的參數#大部分情況下,會創建預編譯語句,但有時候傳遞的是SQL語句本身,不是需要的參數,可以通過$符號表示,比如傳遞參數columns為」col1,col2,col3」,可以寫成下面語句:

但要注意sql的安全性,防止sql注入。

sql元素

定義:

使用:

結果映射

元素介紹

resultMap是MyBatis裡面最複雜的元素,它的作用是定義映射規則、級聯的更新、定製類型轉換器等。

由以下元素構成:

有的實體不存在沒有參數的構造方法,需要使用constructor配置有參數的構造方法:

id指明主鍵列,result配置資料庫欄位和POJO屬性的映射規則:

association、collection用於配置級聯關係的,分別為一對一和一對多,實際中,多對多關係的應用不多,因為比較複雜,會用一對多的關係把它分解為雙向關係。

discriminator用於這樣一種場景:比如我們去體檢,男和女的體檢項目不同,如果讓男生去檢查婦科項目,是不合理的, 通過discriminator可以根據性別,返回不同的對象。

級聯關係的配置比較多,就不在此演示了,可查看文檔進行了解。

延遲載入

級聯的優勢是能夠方便地獲取數據,但有時不需要獲取所有數據,這樣會多執行幾條SQL,性能下降,為了解決這個問題,需要使用延遲載入,只要使用相關級聯數據時,才會發送SQL去取回數據。

在MyBatis的配置中有2個全局的參數 lazyLoadingEnabled 和 aggressiveLazyLoading ,第一個的含義是是否開啟延遲載入功能,第二個的含義是對任意延遲載入屬性的調用,會使延遲載入的對象完整載入,否則只會按需載入。

再理解下aggressiveLazyLoading屬性,比如學生對象的關聯對象如下:

當訪問學生信息的時候,會根據鑒別器把健康的情況也會查找出來;當訪問課程成績的時候,同時也會把學生證信息查找出來,因為在默認情況下,MyBatis是按層級延遲載入的。 但這不是我們需要的,並不希望在訪問成績的時候,去載入學生證的信息,可以設置aggressiveLazyLoading為false,按需進行延遲載入數據。

上面的2個屬性都是全局設置,也可以在association和collection元素上加上屬性值fetchType,它有兩個取值eager和lazy。

緩存

在沒有顯示配置緩存時,只開啟一級緩存,一級緩存是相對於同一個SqlSession而言的,在參數和SQL完全一樣的情況下,使用同一個SqlSession對象調用同一個Mapper的方法,只會執行一次SQL。

如果是不同的SqlSession對象,因為不同SqlSession是相互隔離的,即使用相同的Mapper、參數和方法,還是會再次發送SQL到資料庫去執行。

二級緩存是SqlSessionFactory層面上的,需要進行顯示配置,實現二級緩存的時候,要求POJO必須是可序列化的,只需要簡單配置即可:

這樣很多設置是默認的,有如下屬性可以配置:

eviction:代表緩存回收策略,可選值有LRU最少使用、FIFO先進先出、SOFT軟引用,WEAK弱引用;

flushInterval:刷新間隔時間,單位為毫秒,如果不配置,當SQL被執行時才會刷新緩存;

size:引用數目,代表緩存最多可以存儲多少對象,不宜設置過大,設置過大會導致內存溢出;

readOnly:只讀,意味著緩存數據只能讀取不能修改;

動態SQL

很多時候,需要根據不同的場景組裝查詢條件,MyBatis提供對SQL語句動態的組裝能力。

主要提供以下幾種元素:

if:判斷語句,但條件分支判斷;

choose (when、otherwise):多條件分支判斷;

trim (where、set):處理一些SQL拼裝問題;

foreach:循環語句,在in語句等列舉條件常用;

bind:通過OGNL表達式去自定義一個上下文變數,可以方便使用;

trim可以處理and和逗號拼接的問題,舉例如下:

另外,可以使用set元素設置更新的欄位列表:

下一篇會介紹MyBatis的解析和運行原理。

今天,公司發布新產品 MIX 2S


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 情情說 的精彩文章:

單點登錄與許可權管理本質:許可權管理介紹

TAG:情情說 |