MyBatis之使用resultMap實現高級映射

對於數據庫中對錶的增刪改查操做,咱們知道增刪改都涉及的是單表,而只有查詢操做既能夠設計到單表操做又能夠涉及到多表操做,因此對於輸入映射parameterType而言是沒有所謂的高級映射的,也就是說高級映射只針對於輸出映射(由於高級映射設計到多張表)。前端

前五篇文章咱們都只實現了單表中的字段與pojo的映射,而本篇文章咱們未來講解如何實現多表與pojo之間的高級映射,分別有一對一映射、一對多映射和多對多映射。首先咱們來看看如何使用resultType完成一對一映射。java

1.多表間的一對一查詢

1.1需求

查詢訂單信息關聯查詢用戶信息。這裏咱們知道一個用戶能夠有多張訂單,而一張訂單隻能屬於一個用戶,因此用戶與訂單間的關係是一對多而訂單與用戶間的關係是一對一。因此這裏咱們將訂單表做爲主查詢表來關聯用戶表,從而實現一對一映射。sql

1.2建立表和數據

1
2
3
4
5
6
create table orders( id int primary key auto_increment, 
	user_id int ,
	 number int, 
	 createtime datetime, note varchar(50));

用戶表在第一篇文章中咱們已經建立。

創建oders表和user表對應的pojo對象Orders.java和User.java。數據庫

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Orders
{
	private Integer id;

   private Integer userId;

   private String number;

   private Date createtime;

   private String note;
    	
}

並創建相關的get和set方法,User.java咱們以前已創建。mybatis

1.3sql查詢語句

對於查詢語句,咱們須要知道:1.先肯定主查詢表:訂單表。2.再肯定關聯查詢表:用戶信息表。經過orders關聯查詢用戶使用user_id一個外鍵,只能關聯查詢出一條用戶記錄,咱們使用內鏈接。查詢語句爲:app

1
2
3
SELECT orders.*,user.username,user.sex 
FROM orders,user 
WHERE orders.user_id = user.id

1.4使用resultType實現

經過查詢語句,查詢到的結果同時包括user表和orders表兩張表的列,那麼咱們將結果映射到哪一個pojo對象中呢?若映射到User.java,那查詢結果中對應的orders表的字段必定會遺失;若映射到Orders.java,那查詢結果中對應的user表的字段一樣也會遺失。因此這裏須要咱們針對查詢的結果從新建立一個映射的pojo對象OrderCustom.java:
性能

這裏咱們讓OrderCustom.java繼承自Order.java,這樣咱們就只需在OrderCustom.java中添加user表中的字段便可。由於MyBatis主要的重點在sql語句,因此咱們完成配置和pojo對象的創建後主要的點就放在了sql語句上,因此接下來要定義寫sql語句的mapper.xml和對數據庫進行操做的mapper.java接口了.測試

OrdersMapperCustom.xml文件內容以下:
由於咱們只關心輸出映射,因此在xml中寫sql查詢語句時沒有寫parameterType屬性,而resultType的屬性值我之因此沒有寫全OrderCustom類的全限定性名,是由於咱們在SqlMapperConfig.xml中進行了別名的配置。相應的OrdersMapperCustom.java接口內容以下:spa

而後在測試類中測試:即可完成這兩張表的關聯與咱們自定義的pojo對象的映射。接下來咱們看看如何使用resultMap完成。設計

1.5使用resultMap實現一對一映射

思路:將關聯查詢的信息映射到pojo中,以下:只需在Orders類中建立一個User屬性,將關聯查詢的信息映射到User屬性中。
這樣咱們即可以將查詢的結果映射到Orders.java類中,而不用本身再自定義一個pojo了。

修改OrdersMapperCustom.xml中的內容(添加並使用resultMap標籤),:

而後在OrdersMapperCutom.java中添加方法:

最後測試:發現查詢結果已所有映射到Orders.java類中。

1.6比較resultType和resultMap完成一對一映射

  • resultType:要自定義pojo 保證sql查詢列和pojo的屬性對應,這種方法相對較簡單,因此應用普遍。
  • resultMap:使用association完成一對一映射須要配置一個resultMap標籤,過程有點複雜,若是要實現延遲加載(後面會講)就只能用resultMap實現 ,若是爲了方便對關聯信息進行解析,也能夠用association將關聯信息映射到pojo中方便解析。

2.多表間的一對多查詢

2.1需求

查詢全部訂單信息及訂單下的訂單明細信息。分析:一個訂單能夠能夠有多個訂單明細,而一個訂單明細只屬於一個訂單,因此訂單與訂單明細間的關係爲一對多。

2.2建立表和數據

1
2
3
create table orderdetail( id int primary key auto_increment, orders_id int, items_id int, items_num int);//建立訂單明細表

訂單表咱們已經建立

建立和訂單明細表對應的pojo對象:

1
2
3
4
5
6
7
8
9
10
11
public class Orderdetail
{
   	private Integer id;

   	private Integer ordersId;

   	private Integer itemsId;

   	private Integer itemsNum;
   	
   }

 

並建立相關的set和get方法。

2.3sql查詢語句

1.先肯定主查詢表:訂單表。2.再肯定關聯查詢表:用戶表加訂單明細表。經過orderdetail關聯查詢訂單使用orders_id一個外鍵,只能關聯查詢出一條訂單記錄,咱們使用內鏈接。查詢語句爲:

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完成關聯信息映射到集合對象中。在orders類中建立集合屬性:

而後修改OrdersMapperCustom.xml中的信息:
並在其中添加resultMap的定義:

而後在OrdersMapperCutom.java中添加方法:

最後進行測試:

發現查詢的結果已所有映射到pojo對象Orders.java的屬性中。

3.多對多查詢(之後我會實現的)

首先咱們應該明確的是:一對可能是多對多的特例。

需求1:查詢顯示字段:用戶帳號、用戶名稱、用戶性別、商品名稱、商品價格(最多見)
企業開發中常見明細列表,用戶購買商品明細列表,
使用resultType將上邊查詢列映射到pojo輸出。

需求2:查詢顯示字段:用戶帳號、用戶名稱、購買商品數量、商品明細(鼠標移上顯示明細)
使用resultMap將用戶購買的商品明細列表映射到user對象中。

講完如何使用resultMap完成多表間的查詢結果與pojo對象的高級映射,這裏咱們還須要補充一個使用resultMap實現延遲加載的知識點。

4.延遲加載

4.1使用延遲加載的意義

在進行數據查詢時,爲了提升數據庫查詢性能,儘可能使用單表查詢,由於單表查詢比多表關聯查詢速度要快。

若是查詢單表就能夠知足需求,一開始先查詢單表,當須要關聯信息時,再關聯查詢,當須要關聯信息再查詢這個叫延遲加載。

mybatis中resultMap提供延遲加載功能,經過resultMap配置延遲加載,但須要在MyBatis的配置文件中進行相關配置,以下:

4.2配置mybatis支持延遲加載

設置項 描述 容許值 默認值
lazyLoadingEnabled 全局性設置懶加載。若是設爲‘false’,則全部相關聯的都會被初始化加載。 true|false false
aggressiveLazyLoading 當設置爲‘true’的時候,懶加載的對象可能被任何懶屬性所有加載。不然,每一個屬性都按需加載。 true | false true

而後在SqlMapperConfig.xml中添加以下配置信息:

4.3一對一延遲加載的實現

4.3.1實現思路

需求:查詢訂單及用戶的信息,一對一查詢。

剛開始咱們只查詢訂單信息。而當須要用戶信息時調用Orders類中的getUser()方法執行延遲加載 ,向數據庫發出sql。代碼實現以下:

在OrderMapperCustom.xml文件中添加以下信息:

並定義resultMap標籤:

而後在OrderMapperCustom.java接口中添加以下方法:

最後是測試代碼:

4.4一對多延遲加載的實現

一對多延遲加載的方法同一對一延遲加載,在collection標籤中配置select內容。

5.resultType、resultMap、延遲加載使用場景總結

延遲加載:
延遲加載實現的方法多種多樣,在只查詢單表就能夠知足需求,爲了提升數據庫查詢性能使用延遲加載,再查詢關聯信息。

mybatis提供延遲加載的功能用於service層。

resultType:做用:將查詢結果按照sql列名pojo屬性名一致性映射到pojo中。

場合:常見一些明細記錄的展現,將關聯查詢信息所有展現在頁面時,此時可直接使用resultType將每一條記錄映射到pojo中,在前端頁面遍歷list(list中是pojo)便可。

resultMap:使用association和collection完成一對一和一對多高級映射。

association:做用:將關聯查詢信息映射到一個pojo類中。

場合:爲了方便獲取關聯信息可使用association將關聯訂單映射爲pojo,好比:查詢訂單及關聯用戶信息。

collection:做用:將關聯查詢信息映射到一個list集合中。

場合:爲了方便獲取關聯信息可使用collection將關聯信息映射到list集合中,好比:查詢用戶權限範圍模塊和功能,可以使用collection將模塊和功能列表映射到list中。

相關文章
相關標籤/搜索