上一篇博文總結了一下一對一的映射,本文主要總結一下一對多的映射,從上一篇文章中的映射關系圖中可知,訂單項和訂單明細是一對多的關系,所以本文主要來查詢訂單表,然后關聯訂單明細表,這樣就有一對多的問題出來了。
首先還是先寫sql語句,在寫sql語句的時候遵循兩點:
- 查詢的主表是哪個? 訂單表
- 查詢的關聯表是哪個? 訂單明細表
明確了主表和關聯表,下面就可以寫sql了,我們在上一節的sql基礎上添加訂單明細表的關聯即可。
SELECT orders.*, user.`username`, user.`sex`, user.`address`, orderdetail.`id` orderdetail_id, orderdetail.`items_id`, orderdetail.`items_num`, orderdetail.`orders_id` FROM orders, USER, orderdetail WHERE orders.`user_id`=user.`id` AND orders.`id` = orderdetail.`orders_id`
這樣我們就查詢出了訂單表中的所有字段,user表和orderdetail表的部分字段,當然也可以查詢所有字段,這個根據具體需求來定。看一下查詢結果:
從結果中可以看出,訂單的信息有重復,訂單項是不重復的,因為一對多嘛,這很好理解。所以如果我們用resultType來做映射的話就會出現訂單信息的重復,我們不希望出現這個結果,即對orders的映射不能出現重復記錄的情況。那么我們就需要在Orders.Java類中添加一個List<OrderDetail> orderDetails
屬性來封裝訂單明細項(比較簡單,代碼就不貼了),最終會將訂單信息映射到Orders中,該訂單所對應的訂單明細映射到Orders中的orderDetails屬性中(這跟hibernate中有點類似,如果是hibernate,也會在Orders類中維護一個裝OrderDetail的List)。
有了這個思路,接下來就開始寫映射文件了。
<select id="findOrdersAndOrderDetailResultMap" resultMap="OrdersAndOrderDetailResultMap"> SELECT orders.*, user.`username`, user.`sex`, user.`address`, orderdetail.`id` orderdetail_id, orderdetail.`items_id`, orderdetail.`items_num`, orderdetail.`orders_id` FROM orders, USER, orderdetail WHERE orders.`user_id`=user.`id` AND orders.`id` = orderdetail.`orders_id` </select>
所以我們要定義一個名為OrdersAndOrderDetailResultMap的resultMap,如下:
<resultMap type="mybatis.po.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap"> <!-- 配置映射訂單信息和關聯的用戶信息和上面的一樣,繼承上面的即可 --> <!-- 配置關聯的訂單明細信息 --> <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"/> </collection> </resultMap>
這里看到了一個繼承,因為訂單信息和關聯的用戶信息和前面一對一是完全一樣的,我們就不需要再寫一遍了,<resultMap>
支持繼承,直接繼承那個resultMap即可,然后加上訂單明細這部分即可。
<collection>
是用來處理一對多映射的標簽,property屬性是Orders.java類中對應的裝OrderDetail的List的屬性名,就是剛剛定義的那個List,ofType屬性表示該List中裝的是啥,可以是完全限定名,也可以是別名。然后<collection>
里面的標簽和屬性就和前面一樣了,不再贅述。
然后定義一下mapper接口即可:
public interface UserMapperOrders { //省去不相關代碼 //查詢訂單(關聯用戶)及訂單明細 public List<Orders> findOrdersAndOrderDetailResultMap() throws Exception; }
到此位置,一對多的映射就寫好了,下面測試一下:
@Test public void testFindOrdersAndOrderDetailResultMap() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapperOrders userMapperOrders = sqlSession.getMapper(UserMapperOrders.class); List<Orders> list = userMapperOrders.findOrdersAndOrderDetailResultMap(); System.out.println(list); }
一對多就總結到這吧,下一篇博文將總結一下mybatis中多對多映射。
文章列表