實際的開發中,對數據庫的操作常常會涉及到多張表,這在面向對象中就涉及到了對象與對象之間的關聯關系。針對多表之間的操作,MyBatis提供了關聯映射,
通過關聯映射就可以很好的處理對象與對象之間的關聯關系。
1.1 關聯關系概述
在關系型數據庫中,多表之間存在着三種關聯關系,分別為一對一、一對多和多對多,如下圖所示:
三種關系如下:
-
一對一:在任意一方引入對方主鍵作為外鍵。
-
一對多:在“多”的一方,添加“一”的一方的主鍵作為外鍵。
-
多對多:產生中間關系表,引入兩張表的主鍵作為外鍵,兩個主鍵成為聯合主鍵或使用新的字段作為主鍵。
在Java中,通過對象也可以進行關聯關系描述,如圖下圖所示:
-
一對一的關系:就是在本類中定義對方類型的對象,如A類中定義B類類型的屬性b,B類中定義A類類型的屬性a。
-
一對多的關系:就是一個A類類型對應多個B類類型的情況,需要在A類中以集合的方式引入B類類型的對象,在B類中定義A類類型的屬性a。
-
多對多的關系:在A類中定義B類類型的集合,在B類中定義A類類型的集合。
1.2 一對一
在現實生活中,一對一關聯關系是十分常見的。例如,一個人只能有一個身份證,同時一個身份證也只會對應一個人
<resultMap>元素中,包含了一個<association>子元素,MyBatis就是通過該元素來處理一對一關聯關系的。
在<association>元素中,通常可以配置以下屬性:
-
property:指定映射到的實體類對象屬性,與表字段一一對應;
-
column:指定表中對應的字段;
-
javaType:指定映射到實體對象屬性的類型;
-
select:指定引入嵌套查詢的子SQL語句,該屬性用於關聯映射中的嵌套查詢;
-
fetchType:指定在關聯查詢時是否啟用延遲加載。該屬性有lazy和eager兩個屬性值,默認值為lazy(即默認關聯映射延遲加載)。
MyBatis加載關聯關系對象主要通過兩種方式:嵌套查詢和嵌套結果。
-
嵌套查詢:嵌套查詢是通過執行另外一條SQL映射語句來返回預期的復雜類型。
嵌套查詢是在查詢SQL中嵌入一個子查詢SQL; 嵌套查詢會執行多條SQL語句; 嵌套查詢SQL語句編寫較為簡單;
-
嵌套結果:嵌套結果是使用嵌套結果映射來處理重復的聯合結果的子集。
嵌套結果是一個嵌套的多表查詢SQL; 嵌套結果只會執行一條復雜的SQL語句; 嵌套結果SQL語句編寫比較復雜;
雖然使用嵌套查詢的方式比較簡單,但是嵌套查詢的方式要執行多條SQL語句,這對於大型數據集合和列表展示不是很好,
因為這樣可能會導致成百上千條關聯的SQL語句被執行,從而極大的消耗數據庫性能並且會降低查詢效率。
使用<association>元素進行一對一關聯映射非常簡單,只需要參考如下兩種示例配置即可。
- 嵌套查詢,property指的是類屬性,column指的是表字段,select表示嵌套的子查詢,javaType表示關聯屬性類型。
<association property="card" column="card_id"
javaType="com.itheima.po.IdCard" select="com.itheima.mapper.IdCardMapper.findCodeById" />
- 嵌套結果,property指的是類屬性,column指的是表字段,javaType表示關聯屬性類型。
<association property="card" javaType="com.itheima.po.IdCard">
<id property="id" column="card_id" />
<result property="code" column="code" />
</association>
1.3 一對多
開發人員接觸更多的關聯關系是一對多(或多對一)。例如,一個用戶可以有多個訂單,同時多個訂單歸一個用戶所有。
<resultMap>元素中,包含了一個<collection>子元素,MyBatis就是通過該元素來處理一對多關聯關系的。
<collection>子元素的屬性大部分與<association>元素相同,但其還包含一個特殊屬性--ofType 。
- ofType:ofType屬性與javaType屬性對應,它用於指定實體對象中集合類屬性所包含的元素類型。
<collection>元素的使用也非常簡單,同樣可以參考如下兩種示例進行配置,具體代碼如下:
- 嵌套查詢,property指的是類屬性,column指的是表字段,select表示嵌套的子查詢,ofType表示關聯的集合類屬性類型。
<collection property="ordersList" column="id" ofType="com.itheima.po.Orders"
select=" com.itheima.mapper.OrdersMapper.selectOrders" />
- 嵌套結果,property指的是類屬性,column指的是表字段,ofType表示關聯的集合類屬性類型。
<collection property="ordersList" ofType="com.itheima.po.Orders">
<id property="id" column="orders_id" />
<result property="number" column="number" />
</collection>
1.3 多對多
在實際項目開發中,多對多的關聯關系也是非常常見的。以訂單和商品為例,一個訂單可以包含多種商品,而一種商品又可以屬於多個訂單
在數據庫中,多對多的關聯關系通常使用一個中間表來維護,中間表中的訂單id作為外鍵參照訂單表的id,商品id作為外鍵參照商品表的id。
在MyBatis中,多對多的關聯關系查詢,同樣可以使用前面介紹的 <collection>元素進行處理(其用法和一對多關聯關系查詢語句用法基本相同)。
小結
主要學習了MyBatis中的數據表之間以及對象之間的關聯關系,以及MyBatis框架中對關聯關系的處理。
以上內容是根據Java EE企業級應用開發教程(Spring+Spring MVC+MyBatis)做的一些筆記和總結。