文章出處

本文來總結一下mybatis中的多對多映射,從第8節的文章中可以看出,用戶表和商品表示多對多關系,它們兩的多對多是通過訂單項和訂單明細這兩張表所關聯起來的,那么這一節主要來總結一下用戶表和商品表之間的多對多映射。 
  首先在上一節的基礎上繼續寫sql,

 

SELECT 
  orders.*,
  user.`username`,
  user.`sex`,
  user.`address`,
  orderdetail.`id` orderdetail_id,
  orderdetail.`items_id`,
  orderdetail.`items_num`,
  orderdetail.`orders_id`,
  items.`name` items_name,
  items.`detail` items_detail,
  items.`price` items_price
FROM
  orders,
  USER,
  orderdetail,
  items
WHERE orders.`user_id`=user.`id` AND orders.`id` = orderdetail.`orders_id` AND orderdetail.`items_id`=items.id

 

因為多對多比較復雜,總公共有四張表,我們先來分析一下思路:

 

  1. 將用戶信息映射到User中;
  2. 在User類中添加訂單列表屬性List<Orders>ordersList,將用戶創建的訂單映射到ordersList中;
  3. 在Orders中添加訂單明細列表屬性List<OrderDetail>orderDetails,將訂單的明細映射到orderDetails中;
  4. 在OrderDetail中添加Items屬性,將訂單明細所對應的商品映射到Items中。
  5. 經過這樣分析后,感覺雖然有點復雜,但是好像不是很難的樣子,映射的方法也跟前面的一樣,只不過這里表有點多,關系有點復雜。下面來寫映射文件:

 

<select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap">
    SELECT 
      orders.*,
      user.`username`,
      user.`sex`,
      user.`address`,
      orderdetail.`id` orderdetail_id,
      orderdetail.`items_id`,
      orderdetail.`items_num`,
      orderdetail.`orders_id`,
      items.`name` items_name,
      items.`detail` items_detail,
      items.`price` items_price
    FROM
      orders,
      USER,
      orderdetail,
      items
    WHERE orders.`user_id`=user.`id` AND orders.`id` = orderdetail.`orders_id` AND orderdetail.`items_id`=items.`id`
</select>

 

接下來,寫名為UserAndItemsResultMap的resultMap,由于主表查詢的是User,所以在resultMap中的type應該寫成User的完全限定名或者別名:

<resultMap type="mybatis.po.User" id="UserAndItemsResultMap">
    <!-- 用戶信息 -->
    <id column="user_id" property="id"/>
    <result column="username" property="username"/>
    <result column="sex" property="sex"/>
    <result column="address" property="address"/>
    <!-- 訂單信息 -->
    <!-- 一個用戶對應多個訂單,使用collection -->
    <collection property="ordersList" ofType="mybatis.po.Orders">
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
        <!-- 訂單明細信息 -->
        <!-- 一個訂單包括多個明細,使用collection -->
        <collection property="orderdetails" ofType="mybatis.po.Orderdetail">
            <id column="orderdetail_id" property="id"/>
            <result column="items_id" property="itemsId"/>
            <result column="items_num" property="itemsNum"/>
            <result column="orders_id" property="ordersId"/>
            <!-- 商品信息 -->
            <!-- 一個明細對應一個商品信息,使用association -->
            <association property="items" javaType="mybatis.po.Items">
                <id column="items_id" property="id"/>
                <result column="items_name" property="name"/>
                <result column="items_detail" property="detail"/>
                <result column="items_price" property="price"/>
            </association>
        </collection>
    </collection>
</resultMap>

是不是看起來有點復雜了,但是很有條理,一步步的深入即可,仔細看看,其實不是很復雜,就是有點多而已,一個個套進去唄~ 
  下面就是寫mapper接口了:

 

public interface UserMapperOrders {

    //省去不相關代碼

    //查詢用戶購買商品信息
    public List<User> findUserAndItemsResultMap() throws Exception;

}

 

測試一下:

@Test
public void findUserAndItemsResultMap() throws Exception {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapperOrders userMapperOrders = sqlSession.getMapper(UserMapperOrders.class);
    List<User> list = userMapperOrders.findUserAndItemsResultMap();
    System.out.println(list);
}

這樣多對多的映射就搞定了。不過還有個問題,就是這里多對多的查詢會把所有關聯的表的信息都查詢出來,然后放到pojo中的對應的List或者某個類中,所以即使我只查了個用戶信息,但是這個用戶里包含了訂單,訂單項,商品等信息,感覺裝的有點多,好像有時候并不需要這么多冗余的數據出來,但是如果用resultType的話查詢出來的字段必須對應pojo中的屬性,如果有List等,需要手動裝入才行。所以下面總結一下對于這種查詢數據比較多的時候,resultType和resultMap各有什么作用?

 

  1. 比如我們只需要將查詢用戶購買的商品信息明細清單(如用戶名、用戶地址、購買商品名稱、購買商品時間、購買商品數量),那么我們完全不需要其他的信息,這個時候就沒必要使用resultMap將所有的信息都搞出來,我們可以自己定義一個pojo,包含我們需要的字段即可,然后查詢語句只查詢我們需要的字段,這樣使用resultType會方便很多。
  2. 如果我們需要查詢該用戶的所有詳細信息,比如用戶點擊該用戶或者鼠標放上去,會出來跟該用戶相關的訂單啊,訂單明細啊,商品啊之類的,然后我們要點進去看下詳細情況的時候,那就需要使用resultMap了,必須將所有信息都裝到這個User中,然后具體啥信息再從User中取,很好理解。
  3. 總結一點:使用resultMap是針對那些對查詢結果映射有特殊要求的功能,,比如特殊要求映射成list中包括多個list。否則使用resultType比較直接。

到這里,mybatis的多對多映射就總結完了。 

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()