天天看點

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢

前言

       當我們學習heribnate的時候,也就是SSH架構的網上商城的時候,我們就學習過它對應的進階映射,一對一映射,一對多映射,多對多映射。對于SSM的Mybatis來說,肯定也是差不多的。既然開了頭了,我們就也來簡單說一些Mybatis的進階映射。當然說到這些東西的時候,最簡單也最常用的就是級聯查詢,是以我們就以幾個簡單的級聯查詢為例,分别說一下Mybatis的一對一、一對多、多對多查詢。

一、一對一映射

1、需求:

       電商類做買賣,使用者送出訂單後,某寶根據訂單資訊和客戶的姓名、位址派送,現在查詢所有的訂單資訊,關聯查詢下但使用者資訊。

(1)首先确定執行的sql語句為:

[sql]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. <span style="font-size:18px;">SELECT orders.*,user.username,userss.address FROM orders,user WHEREorders.user_id = user.id</span>  

resultType方式解決這個問題:

(1)定義po類:

[java]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. public class OrdersCustom extends Orders {  //OrdersCustom類繼承Orders類後OrdersCustom類包括了Orders類的所有字  

[java]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. 段,隻需要定義使用者的資訊字段即可。  
  2.     private String username;// 使用者名稱  
  3.     private String address;// 使用者位址  
  4.     public String getUsername(){  
  5.                 return username;  
  6.     }  
  7.     public String setUsername(String username){  
  8.                 this.username=username;  
  9.     }  
  10.      ……  
  11. }  

(2)Mapper映射檔案:

[html]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. <!-- 查詢所有訂單資訊 -->  
  2.     <select id="findOrdersList" resultType="cn.itcast.mybatis.po.OrdersCustom">  
  3.     SELECT  
  4.     orders.*,  
  5.     user.username,  
  6.     user.address  
  7.     FROM  
  8.     orders,    user  
  9.     WHERE orders.user_id = user.id  
  10.     </select>  

(3)定義mapper接口:

[java]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. <span style="font-size:18px;">public List<OrdersCustom> findOrdersList() throws Exception;</span>  

(4)測試:

[java]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. Public void testfindOrdersList()throws Exception{  
  2.        //擷取session  
  3.        SqlSession session = sqlSessionFactory.openSession();  
  4.        //獲限mapper接口執行個體  
  5.        UserMapper userMapper = session.getMapper(UserMapper.class);  
  6.        //查詢訂單資訊  
  7.        List<OrdersCustom> list =userMapper.findOrdersList();  
  8.        System.out.println(list);  
  9.        //關閉session  
  10.        session.close();  
  11.     }  

使用resultMap解決問題:

(1)定義resultMap:

[html]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. <!-- 訂單資訊resultmap___需要關聯查詢映射的是使用者資訊,使用association将使用者資訊映射到訂單對象的使用者屬性中 -->  
  2. <resultMap type="cn.itcast.mybatis.po.Orders"id="userordermap">  
  3. <!-- 這裡的id,是mybatis在進行一對一查詢時将user字段映射為user對象時要使用,必須寫 -->  
  4. <id property="id" column="id"/>  
  5. <resultpropertyresultproperty="user_id" column="user_id"/>  
  6. <resultpropertyresultproperty="number" column="number"/>  
  7. <associationpropertyassociationproperty="user" javaType="cn.itcast.mybatis.po.User">  
  8. <!-- 這裡的id為user的id,如果寫上表示給user的id屬性指派 -->  
  9. <id property="id" column="user_id"/>  
  10. <resultpropertyresultproperty="username" column="username"/>  
  11. <resultpropertyresultproperty="address" column="address"/>  
  12. </association>  
  13. </resultMap>  

(2)調用resultMap:

[html]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. <select id="findOrdersListResultMap" resultMap="userordermap">  
  2.     SELECT  
  3.     orders.*,  
  4.     user.username,  
  5.     user.address  
  6.     FROM  
  7.     orders,    user  
  8.     WHERE orders.user_id = user.id  
  9. </select>  

(3)定義mapper接口

一對一查詢總結:

       個人認為啊,這種情況下使用resultType定義輸出映射相對簡單,因為這樣隻需要去添加一個po類就行了,按需求添加額外需要的屬性,就可以完成映射。而相對于resultType來說,resultMap就顯得稍微麻煩一些了,他需要特别定義resultMap來映射相關聯表的實體屬性。

二、一對多查詢:

1、需求:

       繼上面的需求,查詢所有訂單資訊及訂單下的訂單明細資訊(一個訂單資訊下面或有很多商品,這個女生買護膚品的時候應該很有感觸吧。是以訂單資訊與訂單明細是一對多的關系)

(1)确定在資料庫執行的sql語句:

[sql]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. Select  orders.*, user.username, user.address,orderdetail.idorderdetail_id,orderdetail.items_id,   
  2. orderdetail.items_num FROM orders,user,orderdetail     
  3. WHERE orders.user_id = user.id AND orders.id = orderdetail.orders_id  

  執行結果:

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢

(2)定義po類:

[java]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. public class Orders{  
  2.     private Integer id;  
  3.     private Integer userId;  
  4.     private String number;  
  5.     private Date createtime;  
  6.     private String note;  
  7.     private User user;  
  8.     private List<OrderDetial> orderDetails;  
  9.     //getter、setter  
  10. }  

(3)定義resultMap

[html]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. <!-- 訂單資訊resultmap -->  
  2. <resultMaptyperesultMaptype="cn.itcast.mybatis.po.Orders"id="userorderdetailmap">  
  3. <id property="id"column="id"/>  
  4. <result property="user_id" column="user_id"/>  
  5. <result property="number" column="number"/>  
  6. <association property="user" javaType="cn.itcast.mybatis.po.User">  
  7. <id property="id" column="user_id"/>  
  8. <result property="username" column="username"/>  
  9. <result property="address" column="address"/>  
  10. </association>  
  11. <collectionpropertycollectionproperty="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">  
  12.     <id property="id" column="orderdetail_id"/>  
  13.     <result property="items_id" column="items_id"/>  
  14.     <result property="items_num" column="items_num"/>  
  15. </collection>  
  16. </resultMap>  

       大家可以跟上面對比一下,這兩個resultMap除了對訂單詳細的映射定義外,其他的是完全一樣的,現在問題來了,我們需要重新定義上面重複的映射資訊嗎?答案是不用,resultMap具有可繼承特性,我們隻需要繼承上面的resultMap(userordermap),然後隻定義别的就可以了,如下:

[html]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. <resultMaptyperesultMaptype="cn.itcast.mybatis.po.Orders" id="userorderdetailmap" extends="userordermap">  
  2. <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">  
  3.    <id property="id" column="orderdetail_id"/>  
  4.    <result property="items_id" column="items_id"/>  
  5.    <result property="items_num" column="items_num"/>  
  6. </collection>  
  7. </resultMap>  

使用extends來繼承訂單資訊resultmap:userordermap

(4)實作調用:

[html]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. <selectidselectid="findOrdersDetailList" resultMap="userorderdetailmap">  
  2.     SELECT  
  3.     orders.*,  
  4.     user.username,  
  5.     user.address,  
  6.     orderdetail.id orderdetail_id,  
  7.     orderdetail.items_id,  
  8.     orderdetail.items_num  
  9.     FROM orders,user,orderdetail  
  10.     WHERE orders.user_id = user.id  
  11.     AND orders.id =orderdetail.orders_id  
  12. </select>  

(5)定義mapper接口:

[java]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. publicList<Orders>findOrdersDetailList () throws Exception;  

(6)來測試一下:

[java]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. Public void testfindOrdersDetailList()throws Exception{  
  2.        //擷取session  
  3.        SqlSession session = sqlSessionFactory.openSession();  
  4.        //獲限mapper接口執行個體  
  5.        UserMapper userMapper =session.getMapper(UserMapper.class);  
  6.        //查詢訂單資訊  
  7.        List<Orders> list =userMapper.findOrdersDetailList();  
  8.        System.out.println(list);  
  9.        //關閉session  
  10.        session.close();  
  11.     }  

       這個吧,圖沒有了,可是可以給大家形容一下,就是傳回結果隻有四個訂單資訊,然後每個訂單資訊裡面有兩個商品資訊list壓到這裡面。就這樣,我們就實作了一對多的查詢,為什麼這個例子我們不用resultType來執行,其實結果早就給大家了,上面執行sql的結果圖,就是傳回的資訊清單,實際上隻有四個訂單資訊,但是使用resultType會傳回8條資訊,也就是沒有完成去重,還需要我們去手動去重,了然了嗎?不是很友善

三、多對多查詢

(1)需求:

       查詢使用者購買的商品資訊(一個使用者可以有N個訂單資訊,每個訂單資訊可以有M個商品資訊,是以我們需要查詢所有的使用者資訊,關聯查詢訂單及訂單明細資訊,訂單名資訊中關聯查詢商品資訊)

(2)确定要執行的sql:

[sql]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. SELECT  
  2.          orders.*,  
  3.          USER.username,  
  4.          USER.address,  
  5.          orderdetail.idorderdetail_id,  
  6.          orderdetail.items_id,  
  7.          orderdetail.items_num,  
  8.          items.nameitems_name,  
  9.          items.detailitems_detail  
  10. FROM  
  11.          orders,  
  12.          USER,  
  13.          orderdetail,  
  14.          items  
  15. WHERE  
  16.          orders.user_id= USER .id  
  17. AND orders.id = orderdetail.orders_id  
  18. ANDorderdetail.items_id = items.id  

(3)po類變化:

       在User中添加List<Orders>orders 屬性;在Orders類中加入List<Orderdetail> orderdetails屬性;Items類,不用動

(4)定義resultMap:

[html]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. <resultMap type="cn.itcast.mybatis.po.User"id="userOrderListResultMap">  
  2.        <id column="user_id"property="id"/>  
  3.        <result column="username"property="username"/>  
  4.        <collection property="orders"ofType="cn.itcast.mybatis.po.Orders">  
  5.           <id  column="id"property="id"/>  
  6.           <result property="number" column="number"/>  
  7.           <collection property="orderdetails"ofType="cn.itcast.mybatis.po.Orderdetail">  
  8.                <id  column="orderdetail_id" property="id"/>  
  9.                <result property="ordersId"column="id"/>  
  10.                <result property="itemsId"column="items_id"/>  
  11.                <result property="itemsNum"column="items_num"/>  
  12.                <association property="items"javaType="cn.itcast.mybatis.po.Items">  
  13.                    <id column="items_id" property="id"/>  
  14.                    <result column="items_name" property="name"/>  
  15.                    <result column="items_detail" property="detail"/>  
  16.               </association>  
  17.          </collection>  
  18.      </collection>  
  19. </resultMap>  

(5)調用resultMap:

[html]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. <select id="findUserItemResultMap" resultMap="UserItemResultMap" >          
  2.        select orders.*,  
  3.               user.username,  
  4.               user.sex,  
  5.               user.address,  
  6.               orderdetail.id,  
  7.               orderdetail_id,  
  8.               orderdetail.items_id,  
  9.               orderdetail.items_num,  
  10.               orderdetail.orders_id,  
  11.               item.id item_id,  
  12.               item.name item_name,  
  13.               item.detail item_detail,  
  14.               item.price item_price   
  15.        from orders,user,orderdetail,item   
  16.        where orders.user_id=user.id   
  17.             and orders.id=orderdetail.orders_id   
  18.             and orderdetail.items_id=item.id  
  19. </select>  

到這裡,相信大家能看出點端倪來了吧,我們一直都是用<collection></collection>和<association></association>分别對集合和實體進行關聯映射,而且它們層層嵌套的方式就跟實體之間層層嵌套的方式一樣:user中包含orders,orders中包含orderdetail,orderdetail中包含item。

(6)然後定義mapper接口:

[java]  view plain copy  print?

【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
【Mybatis進階映射】一對一映射、一對多映射、多對多映射前言一、一對一映射二、一對多查詢:三、多對多查詢
  1. public interface UserMapper {    List<User> findUserItemResultMap() throws Exception;}  

結果,就請大家自己去動手實驗一下吧!

到此,我們的Mybatis進階映射之一對一,一對多,多對多映射就分享完了,期間自己又有點收獲,總結一下:

1、resultType:将查詢結果按照sql列名pojo屬性名一緻性映射到pojo中。常見一些明細記錄的展示,比如使用者購買商品明細,将關聯查詢資訊全部展示在頁面時,此時可直接使用resultType将每一條記錄映射到pojo中,在前端頁面周遊list(list中是pojo)即可。

2、resultMap:使用association和collection完成一對一和一對多進階映射(對結果有特殊的映射要求)。其中association見關聯查詢資訊映射到一個pojo對象中,collection将關聯查詢資訊映射到一個list集合中然而,使用resultType無法将查詢結果映射到pojo對象的pojo屬性中,根據對結果集查詢周遊的需要選擇使用resultType還是resultMap。那就要看我們自己的判斷力了。

轉載于:https://www.cnblogs.com/DoubleEggs/p/6243230.html