title: MyBatis之使用resultMap實現(xiàn)高級映射
tags: MyBatis
categories: MyBatis
若圖片無法顯示吠裆,請前往我的博客查看,相應(yīng)文章鏈接:http://codingxiaxw.cn/2016/11/09/37-mybatis%E5%AE%9E%E7%8E%B0%E9%AB%98%E7%BA%A7%E6%98%A0%E5%B0%84/
對于數(shù)據(jù)庫中對表的增刪改查操作推穷,我們知道增刪改都涉及的是單表,而只有查詢操作既可以設(shè)計到單表操作又可以涉及到多表操作瞻佛,所以對于輸入映射parameterType而言是沒有所謂的高級映射的匕垫,也就是說高級映射只針對于輸出映射(因為高級映射設(shè)計到多張表)。
前五篇文章我們都只實現(xiàn)了單表中的字段與pojo的映射除破,而本篇文章我們將來講解如何實現(xiàn)多表與pojo之間的高級映射,分別有一對一映射牧氮、一對多映射和多對多映射。首先我們來看看如何使用resultType完成一對一映射瑰枫。
1.多表間的一對一查詢
1.1需求
查詢訂單信息關(guān)聯(lián)查詢用戶信息踱葛。這里我們知道一個用戶可以有多張訂單,而一張訂單只能屬于一個用戶光坝,所以用戶與訂單間的關(guān)系是一對多而訂單與用戶間的關(guān)系是一對一尸诽。所以這里我們將訂單表作為主查詢表來關(guān)聯(lián)用戶表,從而實現(xiàn)一對一映射盯另。
1.2創(chuàng)建表和數(shù)據(jù)
create table orders( id int primary key auto_increment,
user_id int ,
number int,
createtime datetime, note varchar(50));
用戶表在第一篇文章中我們已經(jīng)創(chuàng)建性含。
建立oders表和user表對應(yīng)的pojo對象Orders.java和User.java。
public class Orders
{
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
}
并建立相關(guān)的get和set方法鸳惯,User.java我們之前已建立商蕴。
1.3sql查詢語句
對于查詢語句,我們需要知道:1.先確定主查詢表:訂單表芝发。2.再確定關(guān)聯(lián)查詢表:用戶信息表绪商。通過orders關(guān)聯(lián)查詢用戶使用user_id一個外鍵,只能關(guān)聯(lián)查詢出一條用戶記錄后德,我們使用內(nèi)連接部宿。查詢語句為:
SELECT orders.*,user.username,user.sex
FROM orders,user
WHERE orders.user_id = user.id
1.4使用resultType實現(xiàn)
通過查詢語句,查詢到的結(jié)果同時包括user表和orders表兩張表的列瓢湃,那么我們將結(jié)果映射到哪個pojo對象中呢理张?若映射到User.java,那查詢結(jié)果中對應(yīng)的orders表的字段一定會遺失绵患;若映射到Orders.java雾叭,那查詢結(jié)果中對應(yīng)的user表的字段同樣也會遺失。所以這里需要我們針對查詢的結(jié)果重新創(chuàng)建一個映射的pojo對象OrderCustom.java:
[圖片上傳失敗...(image-eaab9a-1526379642827)]
這里我們讓OrderCustom.java繼承自O(shè)rder.java落蝙,這樣我們就只需在OrderCustom.java中添加user表中的字段即可织狐。因為MyBatis主要的重點在sql語句,所以我們完成配置和pojo對象的建立后主要的點就放在了sql語句上筏勒,所以接下來要定義寫sql語句的mapper.xml和對數(shù)據(jù)庫進行操作的mapper.java接口了.
OrdersMapperCustom.xml文件內(nèi)容如下:[圖片上傳失敗...(image-4375bd-1526379642828)]
因為我們只關(guān)心輸出映射移迫,所以在xml中寫sql查詢語句時沒有寫parameterType屬性,而resultType的屬性值我之所以沒有寫全OrderCustom類的全限定性名管行,是因為我們在SqlMapperConfig.xml中進行了別名的配置厨埋。相應(yīng)的OrdersMapperCustom.java接口內(nèi)容如下:[圖片上傳失敗...(image-e57c7c-1526379642828)]
然后在測試類中測試:[圖片上傳失敗...(image-3c93b7-1526379642828)]便可完成這兩張表的關(guān)聯(lián)與我們自定義的pojo對象的映射。接下來我們看看如何使用resultMap完成捐顷。
1.5使用resultMap實現(xiàn)一對一映射
思路:將關(guān)聯(lián)查詢的信息映射到pojo中荡陷,如下:只需在Orders類中創(chuàng)建一個User屬性雨效,將關(guān)聯(lián)查詢的信息映射到User屬性中。[圖片上傳失敗...(image-30db7a-1526379642828)]
這樣我們便可以將查詢的結(jié)果映射到Orders.java類中废赞,而不用自己再自定義一個pojo了徽龟。
修改OrdersMapperCustom.xml中的內(nèi)容(添加并使用resultMap標(biāo)簽),:[圖片上傳失敗...(image-ea737c-1526379642828)]
然后在OrdersMapperCutom.java中添加方法:[圖片上傳失敗...(image-d9ce58-1526379642828)]
最后測試:[圖片上傳失敗...(image-701a41-1526379642828)]發(fā)現(xiàn)查詢結(jié)果已全部映射到Orders.java類中。
1.6比較resultType和resultMap完成一對一映射
- resultType:要自定義pojo 保證sql查詢列和pojo的屬性對應(yīng)唉地,這種方法相對較簡單据悔,所以應(yīng)用廣泛。
- resultMap:使用association完成一對一映射需要配置一個resultMap標(biāo)簽耘沼,過程有點復(fù)雜屠尊,如果要實現(xiàn)延遲加載(后面會講)就只能用resultMap實現(xiàn) ,如果為了方便對關(guān)聯(lián)信息進行解析耕拷,也可以用association將關(guān)聯(lián)信息映射到pojo中方便解析讼昆。
2.多表間的一對多查詢
2.1需求
查詢所有訂單信息及訂單下的訂單明細信息。分析:一個訂單可以可以有多個訂單明細骚烧,而一個訂單明細只屬于一個訂單浸赫,所以訂單與訂單明細間的關(guān)系為一對多。
2.2創(chuàng)建表和數(shù)據(jù)
create table orderdetail( id int primary key auto_increment, orders_id int, items_id int, items_num int);//創(chuàng)建訂單明細表
訂單表我們已經(jīng)創(chuàng)建
創(chuàng)建和訂單明細表對應(yīng)的pojo對象:
public class Orderdetail
{
private Integer id;
private Integer ordersId;
private Integer itemsId;
private Integer itemsNum;
}
并創(chuàng)建相關(guān)的set和get方法赃绊。
2.3sql查詢語句
1.先確定主查詢表:訂單表既峡。2.再確定關(guān)聯(lián)查詢表:用戶表加訂單明細表。通過orderdetail關(guān)聯(lián)查詢訂單使用orders_id一個外鍵碧查,只能關(guān)聯(lián)查詢出一條訂單記錄运敢,我們使用內(nèi)連接。查詢語句為:
SELECT orders.*,user.username,user.sex ,orderdetail.id orderdetail_id,orderdetail.items_num,orderdetail.items_id
FROM orders,user,orderdetail
WHERE orders.user_id = user.id AND orders.id=orderdetail.orders_id
2.4使用resultMap進行一對多映射
思路:resultMap 提供collection完成關(guān)聯(lián)信息映射到集合對象中忠售。在orders類中創(chuàng)建集合屬性:[圖片上傳失敗...(image-f90c58-1526379642828)]
然后修改OrdersMapperCustom.xml中的信息:[圖片上傳失敗...(image-458f2c-1526379642828)]
并在其中添加resultMap的定義:[圖片上傳失敗...(image-1952eb-1526379642828)]
然后在OrdersMapperCutom.java中添加方法:[圖片上傳失敗...(image-52ae24-1526379642828)]
最后進行測試:[圖片上傳失敗...(image-dc1052-1526379642828)]
發(fā)現(xiàn)查詢的結(jié)果已全部映射到pojo對象Orders.java的屬性中传惠。
3.多對多查詢(以后我會實現(xiàn)的)
首先我們應(yīng)該明確的是:一對多是多對多的特例。
需求1:查詢顯示字段:用戶賬號稻扬、用戶名稱卦方、用戶性別、商品名稱泰佳、商品價格(最常見)
企業(yè)開發(fā)中常見明細列表盼砍,用戶購買商品明細列表,
使用resultType將上邊查詢列映射到pojo輸出逝她。
需求2:查詢顯示字段:用戶賬號浇坐、用戶名稱、購買商品數(shù)量黔宛、商品明細(鼠標(biāo)移上顯示明細)
使用resultMap將用戶購買的商品明細列表映射到user對象中近刘。
講完如何使用resultMap完成多表間的查詢結(jié)果與pojo對象的高級映射,這里我們還需要補充一個使用resultMap實現(xiàn)延遲加載的知識點。
4.延遲加載
4.1使用延遲加載的意義
在進行數(shù)據(jù)查詢時跌宛,為了提高數(shù)據(jù)庫查詢性能,盡量使用單表查詢积仗,因為單表查詢比多表關(guān)聯(lián)查詢速度要快疆拘。
如果查詢單表就可以滿足需求,一開始先查詢單表寂曹,當(dāng)需要關(guān)聯(lián)信息時哎迄,再關(guān)聯(lián)查詢,當(dāng)需要關(guān)聯(lián)信息再查詢這個叫延遲加載隆圆。
mybatis中resultMap提供延遲加載功能漱挚,通過resultMap配置延遲加載,但需要在MyBatis的配置文件中進行相關(guān)配置,如下:
4.2配置mybatis支持延遲加載
設(shè)置項 | 描述 | 允許值 | 默認值 |
---|---|---|---|
lazyLoadingEnabled | 全局性設(shè)置懶加載渺氧。如果設(shè)為‘false’旨涝,則所有相關(guān)聯(lián)的都會被初始化加載。 | true|false | false |
aggressiveLazyLoading | 當(dāng)設(shè)置為‘true’的時候侣背,懶加載的對象可能被任何懶屬性全部加載白华。否則,每個屬性都按需加載贩耐。 | true | false | true |
然后在SqlMapperConfig.xml中添加如下配置信息:
[圖片上傳失敗...(image-a7d7b6-1526379642828)]
4.3一對一延遲加載的實現(xiàn)
4.3.1實現(xiàn)思路
需求:查詢訂單及用戶的信息弧腥,一對一查詢。
剛開始我們只查詢訂單信息潮太。而當(dāng)需要用戶信息時調(diào)用Orders類中的getUser()方法執(zhí)行延遲加載 管搪,向數(shù)據(jù)庫發(fā)出sql。代碼實現(xiàn)如下:
在OrderMapperCustom.xml文件中添加如下信息:[圖片上傳失敗...(image-c87ce6-1526379642828)]
并定義resultMap標(biāo)簽:[圖片上傳失敗...(image-ef284e-1526379642828)]
然后在OrderMapperCustom.java接口中添加如下方法:[圖片上傳失敗...(image-81952-1526379642828)]
最后是測試代碼:[圖片上傳失敗...(image-f57858-1526379642828)]
4.4一對多延遲加載的實現(xiàn)
一對多延遲加載的方法同一對一延遲加載铡买,在collection標(biāo)簽中配置select內(nèi)容更鲁。
5.resultType、resultMap奇钞、延遲加載使用場景總結(jié)
延遲加載:
延遲加載實現(xiàn)的方法多種多樣岁经,在只查詢單表就可以滿足需求,為了提高數(shù)據(jù)庫查詢性能使用延遲加載蛇券,再查詢關(guān)聯(lián)信息缀壤。
mybatis提供延遲加載的功能用于service層。
resultType:作用:將查詢結(jié)果按照sql列名pojo屬性名一致性映射到pojo中纠亚。
場合:常見一些明細記錄的展示塘慕,將關(guān)聯(lián)查詢信息全部展示在頁面時,此時可直接使用resultType將每一條記錄映射到pojo中蒂胞,在前端頁面遍歷list(list中是pojo)即可图呢。
resultMap:使用association和collection完成一對一和一對多高級映射。
association:作用:將關(guān)聯(lián)查詢信息映射到一個pojo類中。
場合:為了方便獲取關(guān)聯(lián)信息可以使用association將關(guān)聯(lián)訂單映射為pojo蛤织,比如:查詢訂單及關(guān)聯(lián)用戶信息赴叹。
collection:作用:將關(guān)聯(lián)查詢信息映射到一個list集合中。
場合:為了方便獲取關(guān)聯(lián)信息可以使用collection將關(guān)聯(lián)信息映射到list集合中指蚜,比如:查詢用戶權(quán)限范圍模塊和功能乞巧,可使用collection將模塊和功能列表映射到list中。
2018.3.19更
歡迎加入我的Java交流1群:659957958摊鸡。群里目前已有1800人绽媒,每天都非常活躍免猾,但為了篩選掉那些不懷好意的朋友進來搞破壞是辕,所以目前入群方式已改成了付費方式,你只需要支付9塊錢猎提,即可獲取到群文件中的所有干貨以及群里面各位前輩們的疑惑解答获三;為了鼓勵良好風(fēng)氣的發(fā)展,讓每個新人提出的問題都得到解決锨苏,所以我將得到的入群收費收入都以紅包的形式發(fā)放到那些主動給新手們解決疑惑的朋友手中石窑。在這里,我們除了談技術(shù)蚓炬,還談生活松逊、談理想;在這里肯夏,我們?yōu)槟愕膶W(xué)習(xí)方向指明方向经宏,為你以后的求職道路提供指路明燈;在這里驯击,我們把所有好用的干貨都與你分享烁兰。還在等什么,快加入我們吧徊都!
2018.4.21更:如果群1已滿或者無法加入沪斟,請加Java學(xué)習(xí)交流2群:305335626 。群2作為群1的附屬群暇矫,除了日常的技術(shù)交流主之、資料分享、學(xué)習(xí)方向指明外李根,還會在每年互聯(lián)網(wǎng)的秋春招時節(jié)在群內(nèi)發(fā)布大量的互聯(lián)網(wǎng)內(nèi)推方式槽奕,話不多說,快上車吧房轿!
6.聯(lián)系
If you have some questions after you see this article,you can tell your doubts in the comments area or you can find some info by clicking these links.