1. 程式人生 > >Mybatis學習(四)————— 高階對映,一對一,一對多,多對多對映

Mybatis學習(四)————— 高階對映,一對一,一對多,多對多對映

一、單向和雙向

    包括一對一,一對多,多對多這三種情況,但是每一種又分為單向和雙向,在hibernate中我們就詳細解析過這單向和雙向是啥意思,在這裡,在重複一遍,就拿一對多這種關係來講,比如有員工和部門,一個部門中有多個員工,從部門方看,是一對多關係,而多名員工屬於一個部門,是多對一關係,那麼如果我們的業務需求只需要通過部門查詢到所有的員工,那麼我們就只需要進行單向一對多的對映,如果我們需要通過員工來查詢出對應的部門,那麼我們就需要進行單向多對一的對映,而如果我們這兩個業務需求都需要實現,也就是不管從哪一方進行查詢,都需要能夠找到對方,那麼此時就應該編寫雙向一對多或者雙向多對一(雙向一對多和雙向多對一是一樣的意思)。所以,不管是編寫哪一種,都是根據業務需求來進行決策的。這就是單向和雙向的意思。

    什麼是多對多? 

       多對多就是不管從哪一方看,都是一對多,那麼該關係就是多對多。比如學生跟選修課之間,從學生方看,一個學生能選多門選修課,一對多關係,從選修課之間,一門選修課可以被多個學生選擇,也是一對多關係,那麼學生跟選修課就是多對多關係。多對多關係之間都會由第三張表來表示這種關係。而不會相互設定外來鍵。

二、測試環境

       

       

三、一對一對映

    有了上面這個關係圖,那我們測試就好做多了,就拿orders 和user來測試,從orders方看向user方,就是一對一對映。也就是單向一對一,只需要根據orders能找出user即可。

    兩種方案,對映檔案中輸出對映使用resultType和resultMap。這裡只關注對映檔案,全域性配置檔案就不多說了,還是老樣子的配置

    3.1、使用resultType

        UserMapper.xml  

            

        UserExt.java

          因為需要在查詢orders時,將對應的user也查詢出來,那麼使用resultType的話,就需要建立一個OrdersExt,將user和orders中的屬性合併在一起,形成一個新的pojo。這樣就能夠將查詢出來的記錄都對映到該pojo上了

            

    3.2、使用resultMap

        usermapper.xml

            

          resultMap

              使用resultMap的話就不需要構造一個新的pojo,只需要將查詢出來的記錄的值通過resultMap幫我們對映到指定到哪個pojo的哪個屬性上即可。

            

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper    
 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"    
 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.wuhao.onetoone.resultMap.UserMapper">
 6         <!-- 
 7             resultMap
 8             type:返回物件型別。全限定名,如果使用了typeAliases設定別名,則可以使用別名
 9             id:唯一標識,供下面使用
10             id標籤:唯一標識位,也就是主鍵。
11                 column:從資料庫中查詢出來的列名。有時候會使用別名,主要看sql語句返回的列名是什麼
12                 property:對應返回物件中屬性名
13             result標籤:對映普通屬性
14                 column和property跟上面一樣的功能
15          -->
16     <resultMap type="com.wuhao.onetoone.resultMap.Orders" id="findOrdersAndUserReM">
17         <id column="oid" property="id"/>
18         <result column="number" property="number"/>
19         <result column="user_id" property="userId"/>
20         <result column="createtime" property="createtime"/>
21         <!-- 使用者資訊,
22             association:一對一對映
23             property:把關聯查詢的一對一的資訊封裝到哪個物件屬性上
24             javaType:property屬性的型別
25             其他的什麼id,result標籤都跟上面的一樣。
26          -->
27          <association property="user" javaType="com.wuhao.onetoone.resultMap.User">
28              <id column="uid" property="id"/>
29              <result column="username" property="username"/>
30              <result column="sex" property="sex"/>
31          </association>
32     </resultMap>
33 
34     <!-- 
35         使用resultMap就能夠解決這種麻煩,因為resultMap能進行高階對映,說是高階對映,其實就是可以將查詢出來的列表對映到特定
36         的屬性上去。    
37         使用resultMap之後,就會知道resultType的區別在哪裡了
38             resultType:簡單一些,是一種平鋪式的對映,不用層級式對映用這個比較好。需要什麼查什麼
39             resultMap:比較繁瑣,是一種層級式的對映,在企業中如果沒有特殊要求,建議使用resultType來完成一對一對映,
40      -->
41     <select id="findOrdersAndUserByOid" parameterType="int" resultMap="findOrdersAndUserReM">
42         SELECT
43             orders.id oid,
44             orders.number,
45             orders.user_id,
46             orders.createtime,
47             user.id uid,
48             user.username,
49             user.sex
50          FROM orders,user WHERE orders.id = #{id} AND orders.user_id = user.id    
51     </select>
52     
53     
54 </mapper>
複製程式碼
 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper    
 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"    
 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.wuhao.onetoone.resultMap.UserMapper">
 6         <!-- 
 7             resultMap
 8             type:返回物件型別。全限定名,如果使用了typeAliases設定別名,則可以使用別名
 9             id:唯一標識,供下面使用
10             id標籤:唯一標識位,也就是主鍵。
11                 column:從資料庫中查詢出來的列名。有時候會使用別名,主要看sql語句返回的列名是什麼
12                 property:對應返回物件中屬性名
13             result標籤:對映普通屬性
14                 column和property跟上面一樣的功能
15          -->
16     <resultMap type="com.wuhao.onetoone.resultMap.Orders" id="findOrdersAndUserReM">
17         <id column="oid" property="id"/>
18         <result column="number" property="number"/>
19         <result column="user_id" property="userId"/>
20         <result column="createtime" property="createtime"/>
21         <!-- 使用者資訊,
22             association:一對一對映
23             property:把關聯查詢的一對一的資訊封裝到哪個物件屬性上
24             javaType:property屬性的型別
25             其他的什麼id,result標籤都跟上面的一樣。
26          -->
27          <association property="user" javaType="com.wuhao.onetoone.resultMap.User">
28              <id column="uid" property="id"/>
29              <result column="username" property="username"/>
30              <result column="sex" property="sex"/>
31          </association>
32     </resultMap>
33 
34     <!-- 
35         使用resultMap就能夠解決這種麻煩,因為resultMap能進行高階對映,說是高階對映,其實就是可以將查詢出來的列表對映到特定
36         的屬性上去。    
37         使用resultMap之後,就會知道resultType的區別在哪裡了
38             resultType:簡單一些,是一種平鋪式的對映,不用層級式對映用這個比較好。需要什麼查什麼
39             resultMap:比較繁瑣,是一種層級式的對映,在企業中如果沒有特殊要求,建議使用resultType來完成一對一對映,
40      -->
41     <select id="findOrdersAndUserByOid" parameterType="int" resultMap="findOrdersAndUserReM">
42         SELECT
43             orders.id oid,
44             orders.number,
45             orders.user_id,
46             orders.createtime,
47             user.id uid,
48             user.username,
49             user.sex
50          FROM orders,user WHERE orders.id = #{id} AND orders.user_id = user.id    
51     </select>
52     
53     
54 </mapper>
複製程式碼

     3.3、小總結

        現在應該認識到了resultMap和resultType的區別,需要知道resultMap中一對一對映時是怎麼編寫這種對映關係的。 

        上面所側重的重點在對映檔案statement的編寫,

 

四、一對多對映

     查詢訂單資訊,關聯查詢它的訂單明細資訊,orders --》 ordersdetail。 單向一對多關係,一個訂單有多個訂單項。

     4.1、使用resultType

        使用resultType也可以,按照前面的學習,需要構建一個新的pojo,其中包含了訂單項屬性和orders屬性。這個很簡單,而且都會做,就不多說了,主要說說使用resultMap的用法。

     4.2、使用resultMap

            

        其中注意resultMap中的extends的用法,繼承一個resultMap,就把其中的所有配置都繼承過來了,所以這裡只需要編寫一個collection,對映ordersdetail集合。

        pojo類中應該多了一個這個東西

              

 

        這裡主要是關注,一對多時,resultMap中是如何實現的。使用collection。

 

五、多對多對映

      查詢使用者資訊,以及它所購買的商品資訊  user --》 items

      主表:user  

      從表:orders、orderdetail、items

      也就是通過查詢某個user,查詢到orders,通過orders查詢到orderdetail,通過orderdetail查詢到items。

      pojo

        一個使用者擁有多個訂單

            

        一個訂單可以擁有多個訂單明細

              

        一個訂單明細對應一個商品

            

      usermapper.xml

            

        通過上面pojo和sql語句,可以知道,我們寫的resultMap看起來好像需要很複雜,其實不然,一步步一層層進行編寫,也不難。

            

        如果是一對多關係,那麼就使用collection,如果是一對一,那麼就使用association,先寫user到orders,然後在寫orders中的orderdetail,等等,這樣一層層巢狀進去,也很明瞭。不難懂。

 

 

六、總結

      6.1、resultType和resultMap都可以完成高階結果對映

          如果沒有特殊要求,使用resultType方便

      6.2、resultType和resultMap 的一個主要區別就是要應用場景不同

          resultType主要是查詢明細使用

          resultMap主要是層級查詢使用,比如查詢使用者資訊,如何點選查詢訂單,再去查詢訂單資訊

          resultMap可以實現延遲載入,而resultType沒有該功能

      6.3、延遲載入就是我們下一章節要說的東西,這裡就需要注意,resultMap菜可以實現延遲載入,那麼什麼是延遲載入呢?比如上面一對一關係中,通過orders查詢到對應的user,當沒有使用到user時,那麼orders是不會查詢出user的,等當使用user時,才會進行查詢載入,這就是延遲載入,也稱為懶載入,具體下一節講解。下一節還會講解一級快取,二級快取的問題。