?今天是劉小愛自學Java的第119天。
感謝你的觀看,謝謝你。
學習內(nèi)容安排如下:
- 昨天沒有學完的多對多查詢補充。
- resultMap標簽的繼承問題。
- mybatis中的延遲加載。
- colum屬性的一個補充說明。
一、多對多查詢
案例:查詢訂單,查詢出下單人信息并且查詢出訂單詳情中的商品數(shù)據(jù)。
1業(yè)務(wù)分析
一共有4張表,都是基于訂單表的,我們再次梳理下它們的關(guān)系:
- 一對一:訂單和用戶的關(guān)系,所以在訂單類中封裝了一個用戶對象。
- 一對多:訂單和訂單詳情的關(guān)系,所以在訂單實體類中封裝訂單詳情集合。
- 多對多:訂單詳情和商品的關(guān)系,它們之間的關(guān)系是依托于訂單的。
一個訂單對應(yīng)多個訂單詳情,從而引出了多個商品。但是如果在同一個訂單詳情中呢?
一個訂單詳情對應(yīng)一個商品,所以我們在訂單詳情中加入item實體類對象。
這個關(guān)系捋清楚了,代碼也就好寫了。
其中關(guān)于sql語句的編寫:
本來一開始時特不喜歡sql語句大寫字母的,因為個人覺得其可讀性差,就跟枚舉一樣。
不過Navicat中有一個美化SQL的功能,就是將sql語句弄成這個樣子的。
我一想那肯定有它的道理,就試著用了下,慢慢地竟然覺得也挺好看的,真香。
人啊,果然最怕陷入固有的思維,不敢或者說反感去接觸自身不熟悉的東西。
總覺得自己很了解自己,其實根本就不了解。
2代碼編寫
在接口OrderMapper中創(chuàng)建對應(yīng)的查詢方法,關(guān)于方法要保證見名知義。
老實說,這種大駝峰式的命名方式,我還覺得蠻好看的,可讀性很強。
然后在映射文件中編寫對應(yīng)的sql語句。
返回值使用resultMap標簽說明其映射關(guān)系。
其中resultMap標簽中代碼編寫如下:
返回值都是依托于Order這個實體類的。
①一對一關(guān)系
用association標簽說明Order實體類中的user屬性是和User實體類對應(yīng)的。
②一對多關(guān)系
用collection標簽說明Order實體類中的orderdetails和List<Orderdetail>對應(yīng)。
③多對多關(guān)系
在一對多關(guān)系中的一對一關(guān)系為多對多。
在同一訂單詳情中商品和訂單詳情是一對一關(guān)系,所以使用association標簽說明。
值得注意的是:
- autoMapping屬性為true即開啟自動映射,如果控制臺有的值輸出為null,大概率就是沒有設(shè)置自動映射的原因。
- colum屬性,是和數(shù)據(jù)庫中的列名相對應(yīng)的,非order的id就使用對應(yīng)的外鍵id名,如果沒有,我們可以自己創(chuàng)建一個別名。
關(guān)于colum屬性,我做一個詳細說明:
上圖是Navicat中執(zhí)行sql語句后的一張結(jié)果表,因為太長了我把它們分開了,其實就是一張表,數(shù)據(jù)由四張表組成:
該結(jié)果表中的id也就是和主表order中的id。
id1,id2,id3也就是從表各自的id,但是其順序是可變化的,并不能成為表的唯一標識。
所以就使用外鍵的方式來說明從表的id,也就是user_id,item_id這些。
但orderdetail表并沒有外鍵,就在sql語句中給它創(chuàng)建一個別名,也就是detail_id。
二、resultMap的繼承
補充說明下這個小知識點;
在resultMap中有代碼會出現(xiàn)不斷地重復(fù)配置的情況,比如關(guān)于order與user的映射關(guān)系。
如果存在重復(fù)的代碼,可以使用繼承的方式,和Java中一樣也是extend這個關(guān)鍵字。
在extend屬性中說明需要繼承的resultMap標簽對應(yīng)的id即可。
三、延遲加載
延遲加載的作用在于性能上的節(jié)省。
1改造一對一查詢
案例:根據(jù)訂單號查詢出訂單信息,并查詢出該訂單的下單人信息。
我們一開始是使用的一條sql語句完成數(shù)據(jù)庫查詢,可以將其改造成兩條sql語句。
①resultMap標簽中說明返回值。
②association子標簽
通過select指定需要執(zhí)行的查詢語句。
也就是說①中的sql語句執(zhí)行后,通過該屬性讓③中的sql語句執(zhí)行。
這樣就能完成兩條sql語句的依次執(zhí)行了。
2開啟延遲加載
①開啟延遲加載
lazyLoadingEnabled,延遲加載的全局開關(guān),當開啟時,所有關(guān)聯(lián)對象都會延遲加載。
默認值是false,我們需要將其設(shè)定為true。
②開啟按需加載
aggressiveLazyLoading
當開啟時,任何方法的調(diào)用都會加載該對象的所有屬性;否則,每個屬性會按需加載。
默認值為true,這里設(shè)定false,關(guān)閉立即加載,也就是開啟按需加載了。
最后
謝謝你的觀看。
如果可以的話,麻煩幫忙點個贊,謝謝你。