天天看點

MyBatis的多表查詢筆記

随着學習的進步,需求的提高,我們在實際開發中用的最多的還是多表查詢,就讓我們一起學習MyBatis中的多表查詢。

MyBatis的多表查詢筆記
MyBatis的多表查詢筆記
MyBatis的多表查詢筆記

這次使用的是Spring+MyBatis整合的,具體的規範我也不是很清楚,是以并不清楚項目結構是否規範,最終項目結構以實際需求大綱為主。

Dao層

ClazzMapper、StudentMapper作為MyBatis的*Mapper.xml的接口

Tool為提供Service層服務的接口,ToolImpl為該接口的實作類

POJO

兩個表的實體類,并根據業務需求添加了額外的屬性。

并不知道需不需要Tool這個結構,學習階段沒有去實際開發過項目,自己感覺需要吧。。。為service提供服務(假設是個web項目)。

我們需要用MyBatis實作多表查詢的方法主要有兩種:業務代碼實作、SQL語句實作

多表查詢一般有幾種關系?多表查詢分為3種關系:

一對一

一對多

多對多

我們在這裡不讨論多對多,因為需要第三方表才能實作。我們讨論前兩種!

查詢所有學生對應的班級資訊(一對一)

查詢每個班級中所在學生的資訊(一對多)

業務代碼實作分兩種:一種是使用<code>resultType</code>,另一種是使用<code>resultMap</code>,其實這兩者說的是Mapper.xml檔案中的操作語句的标簽屬性名。

其實在我們學習MyBatis的時候resultType我們經常使用到(如果忘記了可以百度),其作用就是表明查詢語句中使用什麼資料類型來接收查詢到的資料。

什麼是業務代碼實作MyBatis的多表查詢?

業務代碼就是用代碼實作的查詢,有時候多表查詢并不一定是需要外鍵連接配接,兩張表并沒有外交連接配接,但是需求可能就需要結合兩張表,我們可以用代碼去控制查詢時表與表之間的關系。具體怎麼操作呢?假如我們現在要實作第一個業務需求(一對一),先寫兩條查詢語句:

我們可以先将所有學生資訊查詢出來,因為t_student的croom就t_class表中的cid字段名,然後再用for循環将每個學生的croom作為條件,查詢croom對應的班級資訊,再存入Student的Clazz屬性,最後輸出即可。

這樣我們就實作了業務代碼的多表查詢,特點是沒有用到連接配接查詢,我們每個查詢語句都是單表查詢,但是我們利用了java業務代碼結合查詢語句實作了多表查詢。

輸出結果:

我們可以看到日志輸出一共有7+1(8)條查詢記錄。這種方法我們是通過用java代碼實作兩張表的關系,是以執行的sql語句有8條

業務代碼:

檢視日志輸出結果:

結果是執行的查詢記錄有7+1(8)條。我們這次并沒有用上面的業務代碼實作多表查詢,而是借助了MyBatis的标簽——resultMap實作了多表查詢。resultMap标簽的屬性介紹都寫在了Mapper.xml檔案中。

結合上訴兩種方式小結:

兩種方式查詢的結果是一樣的,并且都查詢了7+1條語句,7條執行班級的條件查詢,1條執行學生的所有查詢,簡稱:"N+1"方式的多表查詢,先查詢出某個表的全部資訊,根據這個表的資訊查詢出另一個表的資訊。

兩者都是業務代碼實作多表查詢,總的來說就是将平常的連接配接查詢語句拆成了多個單表查詢,用來實作,雖然業務代碼多了一點,但是相對于用一條SQL執行多表查詢來說某種程度降低了難度,比如:用一條SQL實作多表查詢,如果需求很複雜,這個時候我們可以将其部分拆解為單表查詢結合起來,隻要适當合理,不僅僅可以降低難度,也可以友善維護。

區分resultMap和resultType的差別:

resultType:很簡單,就是定義傳回結果值的類型

resultMap:推薦還是看官方文檔吧,我才學疏淺總結的不好怕帶歪,總的來說resultMap也是MyBatis的很重要的核心之一,因為官方就是這樣形容的:resultMap元素是 MyBatis 中最重要最強大的元素。它可以讓你從 90% 的 JDBC ResultSets 資料提取代碼中解放出來,并在一些情形下允許你進行一些 JDBC 不支援的操作

上面這兩種就是使用業務裝配的方式實作了多表查詢(多個單表查詢實作多表查詢)

既然是多表查詢,那麼肯定就有用一條SQL語句查詢實作多表查詢的。

直接上代碼:

再來看看我們調用的結果:

可以看到結果是一樣的,但是執行的sql語句隻有一句。這就是用SQL語句實作多表查詢,特點就是用了連接配接查詢。用的依然是resultMap,可以看出resultMap有多重要了!

上訴介紹了3中不同的方式實作多表查詢,多數使用第二種和第三種,甚至可能搭配使用。

在第二種方式中如果實體類的屬性名與查詢結果最終的字段名相同,MyBatis可以幫我們自動映射到實體類中,如果查詢時設定了别名,就必須用result标簽手動指定指派。

第三章方式中就不能省略result标簽,你想從resultMap取什麼值就必須用result标簽表明,如果省略不寫,MyBatis不會自動幫我們裝配,是以我們必須指明。注意:如果兩張表出現了相同字段名,我們必須在SQL語句中使用别名将他們區分,否則MyBatis會以靠前的字段名資料指派。

既然單個對象指派字段名是<code>association</code>,那麼如果是一對多中的集合對象呢?我們怎麼做?這個時候我們就需要換一個标簽——<code>collection</code>,并且将javaType屬性換成ofType屬性名即可,ofType的屬性我們可以看作是集合的泛型類型,其他的用法一樣,我們這一點必須要區分取開來。

如果我們使用了resultMap,我們就要将select中的resultType換成resultMap,且兩者不能共存。

更多的我們應該結合官方部落格的部分參考來幫助我們學習了解!