【MyBatis框架】高級映射-一對一查詢

一對一查詢
根據上面咱們分析的訂單商品數據模型(連接:12.訂單商品數據模型-分析思路.txt),咱們來寫一下有關一對一的查詢,分別使用了resultType和resultMap指定輸出參數類型

1.一對一查詢使用resultType指定輸出參數類型

1.1需求

查詢訂單信息,關聯查詢建立訂單的用戶信息

1.2resultType

1.2.1sql語句
肯定查詢的主表:訂單表
肯定查詢的關聯表:用戶表
關聯查詢使用內連接?仍是外連接?
因爲orders表中有一個外鍵(user_id),經過外鍵關聯查詢用戶表只能查詢出一條記錄,可使用內連接。java

SELECT 
  orders.*,
  USER.username,
  USER.sex,
  USER.address 
FROM
  orders,
  USER 
WHERE orders.user_id = user.id

1.2.2建立pojo
將上邊sql查詢的結果映射到pojo中,pojo中必須包括全部查詢列名。
下面寫Orders.java對映數據庫表單sql

package cn.edu.hpu.mybatis.PO;

import java.util.Date;

public class Orders {
    private Integer id;
    
    private Integer userId;
    
    private String number;
    
    private Date creattime;
    
    private String note;

    //get和set方法省略...
}

發現原始的Orders.java不能映射所有字段,須要新建立的pojo。
建立 一個pojo繼承包括查詢字段較多的po類。數據庫

package cn.edu.hpu.mybatis.PO;

//Orders訂單的拓展類
//經過此類映射訂單和用戶查詢的結果,讓此類繼承包括字段較多的pojo類
public class OrdersCustom extends Orders{
    
    //添加用戶屬性
    private String username;
    
    private String sex;
    
    private String address;    
    
    //get和set方法省略...
}

1.2.3mapper.xml
OrdersCustomMapper.xml:mybatis

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">


<!-- namespace命名空間,做用就是對sql進行分類化管理,理解sql隔離
注意:使用mapper代理方法開發,namespace有特殊重要的做用 -->
<mapper namespace="cn.edu.hpu.mybatis.mapper.OrdersCustomMapper">
     <!-- 查詢訂單關聯查詢用戶信息 -->
     
     <select id="findOrdersUser" resultType="cn.edu.hpu.mybatis.PO.OrdersCustom">
         SELECT 
          orders.*,
          USER.username,
          USER.sex,
          USER.address 
        FROM
          orders,
          USER 
        WHERE orders.user_id = user.id
     </select>
</mapper>

在SqlMapConfig.xml中咱們掃描了mapper包全部的Mapper映射文件,因此這裏就不在SqlMapConfig.xml中單獨加載Mapper映射文件了。

1.2.4mapper.javaapp

package cn.edu.hpu.mybatis.mapper;

import java.util.List;

import cn.edu.hpu.mybatis.PO.OrdersCustom;

//訂單mapper
public interface OrdersCustomMapper {


    //查詢訂單關聯查詢用戶信息
    public List<OrdersCustom> findOrdersUser() throws Exception;
}

測試:測試

@Test
public void testFindOrdersUser() throws Exception{
    
    SqlSession sqlSession=sqlSessionFactory.openSession();
    //建立代理對象
    OrdersCustomMapper ordersMapperCustom=sqlSession.getMapper(OrdersCustomMapper.class);
    
    //調用mapper的方法
    List<OrdersCustom> list=ordersMapperCustom.findOrdersUser();
    
    for (int i = 0; i < list.size(); i++) {
        OrdersCustom  oc=list.get(i);
        System.out.println(oc.getUsername()+"|"+oc.getSex()+"|"+oc.getAddress());
        
    }
    
    sqlSession.close();
}

測試結果:
張三|男|河南焦做
張三|男|河南焦做
劉莉莉|女|山東威spa


2.一對一查詢使用resultMap指定輸出參數類型

2.1sql語句
同resultType實現的sql

2.2使用resultMap映射的思路

使用resultMap將查詢結果中的訂單信息映射到Orders對象中,在orders類中添加User屬性,將關聯查詢出來的用戶信息映射到orders對象中的user屬性中。

2.3須要Orders類中添加user屬性代理

package cn.edu.hpu.mybatis.PO;

import java.util.Date;

public class Orders {
    private Integer id;
    
    private Integer userId;
    
    private String number;
    
    private Date creattime;
    
    private String note;
    
    //用戶信息
    private User user;
    ...
}

2.4mapper.xml

2.4.1定義resultMapcode

<!-- 訂單查詢關聯用戶的resultMap 
    將整個查詢結果映射到cn.edu.hpu.mybatis.PO.Orders中-->
    <resultMap type="cn.edu.hpu.mybatis.PO.Orders" id="OrdersUserResultMap">
            <!-- 配置映射的訂單信息 -->
                  <!-- id:指定查詢中的惟一標識,訂單信息中的惟一標識,若是有多個列組成惟一標識,
                  那麼就要配置多個id 。
                  column:訂單信息的惟一標識列。
                  property:訂單信息的惟一標識列所映射到Orderds中哪一個屬性-->
                  <id column="id" property="id"/>
                  <result column="user_id" property="userId"/>
                  <result column="number" property="number"/>
                  <result column="creattime" property="creattime"/>
                  <result column="note" property="note"/>
            
            <!-- 配置關聯用戶的用戶信息 -->
            <!-- association:用於映射關聯查詢單個對象的信息。
             property:要將關聯查詢的用戶信息映射到Orders中哪一個屬性-->
            <association property="user" javaType="cn.edu.hpu.mybatis.PO.User">
                <!-- id:關聯查詢用戶的惟一標識
                指定惟一標識用戶信息的列
                javaType:映射到User的哪一個屬性  -->
                <id column="user_id" property="id"/>
                <result column="username" property="username"/>
                  <result column="sex" property="sex"/>
                  <result column="address" property="address"/>
                  
                <result/>
            </association>
    
    </resultMap>

2.4.2statement定義xml

<!-- 查詢訂單關聯查詢用戶信息,使用resultMap -->
     
     <select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap">
         SELECT 
          orders.*,
          USER.username,
          USER.sex,
          USER.address 
        FROM
          orders,
          USER 
        WHERE orders.user_id = user.id
     </select>

2.4.3mapper.java

package cn.edu.hpu.mybatis.mapper;

import java.util.List;

import cn.edu.hpu.mybatis.PO.Orders;
import cn.edu.hpu.mybatis.PO.OrdersCustom;


//訂單mapper
public interface OrdersCustomMapper {
    
    //查詢訂單關聯查詢用戶使用resultMap
    public List<Orders> findOrdersUserResultMap() throws Exception;
}

測試:

@Test
public void testFindOrdersUserResultMap() throws Exception{
    
    SqlSession sqlSession=sqlSessionFactory.openSession();
    //建立代理對象
    OrdersCustomMapper ordersMapperCustom=sqlSession.getMapper(OrdersCustomMapper.class);
    
    //調用mapper的方法
    List<Orders> list=ordersMapperCustom.findOrdersUserResultMap();
    
    for (int i = 0; i < list.size(); i++) {
        Orders  o=list.get(i);
        User u=o.getUser();
        System.out.println(u.getUsername()+"|"+u.getSex()+"|"+u.getAddress());
        
    }
    
    sqlSession.close();
}

測試結果:
張三|男|河南焦做
張三|男|河南焦做
劉莉莉|女|山東威海


3.resultType和resultMap實現一對一查詢小結實現一對一查詢:resultType:使用resultType實現較爲簡單,若是pojo中沒有包括查詢出來的列名,須要增長列名對應的屬性,便可完成映射。若是沒有查詢結果的特殊要求建議使用resultType。resultMap:須要單獨定義resultMap,實現有點麻煩,若是對查詢結果有特殊的要求(好比pojo裏面又含有pojo),使用resultMap能夠完成將關聯查詢映射pojo的屬性中。resultMap能夠實現延遲加載,resultType沒法實現延遲加載。

相關文章
相關標籤/搜索