對於數據庫中對錶的增刪改查操做,咱們知道增刪改都涉及的是單表,而只有查詢操做既能夠設計到單表操做又能夠涉及到多表操做,因此對於輸入映射parameterType而言是沒有所謂的高級映射的,也就是說高級映射只針對於輸出映射(由於高級映射設計到多張表)。前端
前五篇文章咱們都只實現了單表中的字段與pojo的映射,而本篇文章咱們未來講解如何實現多表與pojo之間的高級映射,分別有一對一映射、一對多映射和多對多映射。首先咱們來看看如何使用resultType完成一對一映射。java
查詢訂單信息關聯查詢用戶信息。這裏咱們知道一個用戶能夠有多張訂單,而一張訂單隻能屬於一個用戶,因此用戶與訂單間的關係是一對多而訂單與用戶間的關係是一對一。因此這裏咱們將訂單表做爲主查詢表來關聯用戶表,從而實現一對一映射。sql
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.先肯定主查詢表:訂單表。2.再肯定關聯查詢表:用戶信息表。經過orders關聯查詢用戶使用user_id一個外鍵,只能關聯查詢出一條用戶記錄,咱們使用內鏈接。查詢語句爲:app
1 2 3 |
SELECT orders.*,user.username,user.sex FROM orders,user WHERE orders.user_id = user.id |
經過查詢語句,查詢到的結果同時包括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完成。設計
思路:將關聯查詢的信息映射到pojo中,以下:只需在Orders類中建立一個User屬性,將關聯查詢的信息映射到User屬性中。
這樣咱們即可以將查詢的結果映射到Orders.java類中,而不用本身再自定義一個pojo了。
修改OrdersMapperCustom.xml中的內容(添加並使用resultMap標籤),:
而後在OrdersMapperCutom.java中添加方法:
最後測試:發現查詢結果已所有映射到Orders.java類中。
查詢全部訂單信息及訂單下的訂單明細信息。分析:一個訂單能夠能夠有多個訂單明細,而一個訂單明細只屬於一個訂單,因此訂單與訂單明細間的關係爲一對多。
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方法。
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
思路:resultMap 提供collection完成關聯信息映射到集合對象中。在orders類中建立集合屬性:
而後修改OrdersMapperCustom.xml中的信息:
並在其中添加resultMap的定義:
而後在OrdersMapperCutom.java中添加方法:
發現查詢的結果已所有映射到pojo對象Orders.java的屬性中。
首先咱們應該明確的是:一對可能是多對多的特例。
需求1:查詢顯示字段:用戶帳號、用戶名稱、用戶性別、商品名稱、商品價格(最多見)
企業開發中常見明細列表,用戶購買商品明細列表,
使用resultType將上邊查詢列映射到pojo輸出。
需求2:查詢顯示字段:用戶帳號、用戶名稱、購買商品數量、商品明細(鼠標移上顯示明細)
使用resultMap將用戶購買的商品明細列表映射到user對象中。
講完如何使用resultMap完成多表間的查詢結果與pojo對象的高級映射,這裏咱們還須要補充一個使用resultMap實現延遲加載的知識點。
在進行數據查詢時,爲了提升數據庫查詢性能,儘可能使用單表查詢,由於單表查詢比多表關聯查詢速度要快。
若是查詢單表就能夠知足需求,一開始先查詢單表,當須要關聯信息時,再關聯查詢,當須要關聯信息再查詢這個叫延遲加載。
mybatis中resultMap提供延遲加載功能,經過resultMap配置延遲加載,但須要在MyBatis的配置文件中進行相關配置,以下:
設置項 | 描述 | 容許值 | 默認值 |
---|---|---|---|
lazyLoadingEnabled | 全局性設置懶加載。若是設爲‘false’,則全部相關聯的都會被初始化加載。 | true|false | false |
aggressiveLazyLoading | 當設置爲‘true’的時候,懶加載的對象可能被任何懶屬性所有加載。不然,每一個屬性都按需加載。 | true | false | true |
而後在SqlMapperConfig.xml中添加以下配置信息:
需求:查詢訂單及用戶的信息,一對一查詢。
剛開始咱們只查詢訂單信息。而當須要用戶信息時調用Orders類中的getUser()方法執行延遲加載 ,向數據庫發出sql。代碼實現以下:
在OrderMapperCustom.xml文件中添加以下信息:
而後在OrderMapperCustom.java接口中添加以下方法:
一對多延遲加載的方法同一對一延遲加載,在collection標籤中配置select內容。
延遲加載:
延遲加載實現的方法多種多樣,在只查詢單表就能夠知足需求,爲了提升數據庫查詢性能使用延遲加載,再查詢關聯信息。
mybatis提供延遲加載的功能用於service層。
resultType:做用:將查詢結果按照sql列名pojo屬性名一致性映射到pojo中。
場合:常見一些明細記錄的展現,將關聯查詢信息所有展現在頁面時,此時可直接使用resultType將每一條記錄映射到pojo中,在前端頁面遍歷list(list中是pojo)便可。
resultMap:使用association和collection完成一對一和一對多高級映射。
association:做用:將關聯查詢信息映射到一個pojo類中。
場合:爲了方便獲取關聯信息可使用association將關聯訂單映射爲pojo,好比:查詢訂單及關聯用戶信息。
collection:做用:將關聯查詢信息映射到一個list集合中。
場合:爲了方便獲取關聯信息可使用collection將關聯信息映射到list集合中,好比:查詢用戶權限範圍模塊和功能,可以使用collection將模塊和功能列表映射到list中。