MyBatis之關聯查詢
mybatis實作表與表之間的查詢,将查詢結果集進行映射,主要是resultMap完成進階映射,了解resultMap的使用方法。
1.資料模型
訂單商品模型:
目标:分析表與表之間的關系。
分析步驟:
1、按子產品去分析表,不要将系統全部表一次性分析
2、了解每個表存儲了什麼業務資料
3、了解表中關鍵字段(主鍵、外鍵、索引字段、非空字段)
4、了解表與表之間資料庫級别的關系(外鍵關系)
5、表與表之間的業務關系(一對一、一對多、多對多)
注意:分析表與表之間的業務關系時一定要建立 在某種業務意義基礎上
user表:存儲了購買使用者資訊
網民,在電商系統中注冊成為購買使用者
orders表:存儲了使用者建立的訂單資訊
使用者購買東西,一次不管購買多少商品隻會建立一個訂單
比如:張三一次購買手機、電腦,在orders表插入一條訂單記錄
orderdetail表:存儲使用者建立訂單的詳細資訊,記錄當時使用者購買商品的購買資訊
比如:張三一次購買手機、電腦,在orders表插入一條訂單記錄,在訂單明細表插入兩條記錄,訂單明細表每條記錄對應一個商品資訊
items商品表:存儲了電商系統中的商品資訊,使用者在網站檢視的商品資訊就是來源與這張表
比如:網站銷售手機,在這個表中插入很多的不同型号手機商品資訊
orders—>user:
一個訂單隻能由一個使用者建立,一對一關系
user—>orders:
一個使用者可以建立多個訂單,一對多關系
2.一對一查詢
2.1.需求
查詢訂單關聯查詢使用者資訊
2.2.分析
使用mybatis開發持久層的dao接口時,要分析的重點就是sql語句如何實作?
主查詢表:orders訂單表
關聯查詢表:user使用者資訊
确定關聯查詢方法:包括内連接配接、外連接配接
由于orders表有外鍵user_id,根據user_id去查詢user隻能查詢到一條記錄的。就可以使用内連結。
SELECT
orders.*,
user.username,
user.address
FROM
orders,
USER
WHERE orders.user_id = user.id
2.3基本資料模型po
一個表對應一個po類,表名和po類名一緻,表的屬性和po的屬性一緻。
2.4.resultType實作
resultType映射規則:sql查詢出幾條記錄,隻要保證sql列名和resulttype指定的pojo類型的屬性一緻,可以映射成功,sql查詢出幾條記錄最終映射生成的List<pojo>就有幾個對象。
2.4.1.自定義pojo
由于與表對應的po類的屬性不能夠全部包括下邊列名,是以自定義pojo,屬性名和下邊的列名保持一緻
2.4.2.mapper.xml
2.4.3.mapper.java
2.5.resultMap實作
2.5.1.需求
主查詢是訂單資訊,要将主查詢訂單資訊映射到orders對象中,在orders中建立user屬性,讓關聯查詢出來的使用者資訊映射到orders對象中的user屬性中。其主要目标為了擷取資訊友善,如果想擷取使用者的資訊,調用orders對象的getUser()方法即可。
2.5.2.在orders中建立user屬性
2.5.3.mapper.xml
2.5.4.resultMap
2.5.5.mapper.java
2.6.小結
如果沒有特殊的要求,使用resultType是比較友善,隻要能夠保證sql查詢的列和pojo屬性名一緻可以映射成功,如果pojo中屬性少了,添加屬性即可。
特殊的要求:
如果需要将關聯查詢的資訊映射到pojo的pojo屬性中, 為了擷取資料友善,可以使用resultMap。
如果使用延遲加載,隻能使用resultMap。
建議是使用resultMap即可,在實際中,資料庫中查詢處來的字段名與實體類的屬性名不一定一樣。當一樣的也可以不用去定義,resultMap會自動封裝。
3.一對多查詢
3.1.需求
查詢訂單關聯查詢明細資訊
3.2.分析
主查詢表:orders訂單表
關聯查詢表:orderdetail訂單明細表
使用内連接配接
select
orders.*,
user.username,
user.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num
FROM
orders,
USER ,
orderdetail
WHERE orders.user_id = user.id AND orderdetail.orders_id = orders.id
3.3.映射需求
将主查詢的訂單資訊映射到orders對象中,将訂單關聯的明細資訊映射到orders對象中List<Orderdetail>
根據此需求分析使用resultType不能實作,隻能使用resultMap
3.4.修改orders類添加List屬性
3.5.mapper.xml
3.6.resultMap
3.7.mapper.java
4.association和collection小結
association:用于将關聯查詢資訊映射到單個對象中。
标簽注意使用javaType指定關聯映射的對象類型
collection:用于将關聯查詢資訊映射到集合對象中。
标簽注意使用ofType指定關聯映射的List中pojo的類型。
5.多對多查詢
5.1.需求
查詢使用者資訊及使用者購買的商品資訊
5.2.分析
主查詢表:user使用者資訊
關聯查詢表:orders訂單、orderdetail訂單明細、items商品資訊
采用内連結關聯。
SELECT
orders.*,
user.username,
user.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
items.name items_name,
items.pic items_pic
FROM
orders,
USER,
orderdetail,
items
WHERE orders.user_id = user.id
AND orderdetail.orders_id = orders.id
AND items.id = orderdetail.items_id
5.3.映射需求
在user中設定一個List orders屬性,在order對象中設定List<Orderdetail> orderdeils 屬性,在Orderdetail中設定Items屬性。
最終查詢出來的使用者清單,使用者資訊映射到List<User>中,使用者建立的訂單資訊映射到user中的List<Orders> orders屬性,訂單下的明細映射到order對象中List<Orderdetail> orderdeils 屬性,訂單明細所對應的商品資訊映射到Orderdetail中Items屬性
5.4.修改po類
5.5.mapper.xml
5.6.resultMap
5.7.mapper.java
6.resultMap總結
resultMap實作進階映射,如果對結果有進階映射的需求可以使用reusltMap,需求比如:将一個清單資料映射到pojo的list屬性中采用resultmap。
如果僅僅是将查詢清單簡單映射為List<pojo>方式,清單中每個pojo對應一條記錄,采用resultType即可。
7.延遲加載
- 如果剛開始僅僅查詢一些簡單的資料能夠 滿足使用者的需求時,隻需要查詢簡單的資料(盡量從單表中取資料),當使用者需要查詢關聯資訊時,此時我們再關聯查詢關聯資訊,叫延遲加載,對關聯查詢的資訊進行延遲加載。
- 延遲加載其目的為了提高查詢性能,減輕資料的壓力。
7.1.需求
查詢訂單關聯查詢使用者資訊,對關聯查詢使用者進行延遲加載。
7.2.實作方式一
定義兩個mapper:
1、查詢訂單清單(隻從訂單表查詢),單表查詢
2、根據使用者id查詢使用者資訊。
service調用第一個mapper查詢出訂單資訊在頁面顯示出來
當使用者在頁面點選“檢視使用者”連結時通過service調用第二個mapper查詢使用者資訊。
7.3.resultMap實作延遲加載
7.3.1.打開延遲加載的開關
在SqlMapConfig.xml中配置:
7.3.2.sql語句
查詢訂單的sql:
單表查詢:
select * from orders;
查詢使用者資訊:
根據使用者id查詢使用者資訊
select * from user where id=?
7.3.3.mapper.xml
7.3.4.resultMap定義延遲加載
7.3.5.mapper.java
7.3.6.測試延遲加載
7.3.7.總結
- resultMap提供延遲加載,通過association可以延遲加載一個對象,通過collection可以延遲加載多個對象即集合對象。
- 延遲加載要注意實作的方法多種多樣,主要目的是提高查詢性能,減輕資料庫壓力,先查詢簡單資料,按 需查詢關聯資料。