1. 程式人生 > >Spring+SpringMVC+MyBatis深入學習及搭建(六)——MyBatis關聯查詢

Spring+SpringMVC+MyBatis深入學習及搭建(六)——MyBatis關聯查詢

1.商品訂單資料模型

1.1資料模型分析思路

(1)每張表記錄的資料內容

  分模組對每張表記錄的內容進行熟悉,相當於你學習系統需求(功能)的過程。

(2)每張表重要的欄位設定

  非空欄位、外來鍵欄位

(3)資料庫級別表與表之間的關係

  外來鍵關係

(4)表與表之間的業務關係

  在分析表與表之間的業務關係時,一定要建立在某個業務意義基礎上去分析。

1.2屬性模型分析

2.一對一查詢

2.1需求

查詢訂單資訊,關聯查詢下單使用者資訊。

2.2方法一:resultType

2.2.1sql語句

確定查詢的主表:訂單表

確定查詢的關聯表:使用者表

  關聯查詢使用內連結?還是外連結?

  由於orders表中有一個外來鍵(user_id),通過外來鍵關聯查詢使用者表只能查詢出一條記錄,可使用內連結。

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

2.2.2建立pojo

 將上邊sql查詢的結果對映到pojo中,pojo中必須包括所有查詢列名。

原始Orders.java不能對映全部欄位,需要新建立pojo。

建立一個pojo繼承包括查詢欄位較多的pojo類。

2.2.3mapper.xml

<?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有特殊作用,namespace等於mapper介面地址 --> <mapper namespace="joanna.yan.mybatis.mapper.OrdersCustomMapper"> <!--查詢訂單,關聯查詢使用者資訊 --> <select id="findOrdersUser" resultType="joanna.yan.mybatis.entity.OrdersCustom"
> SELECT orders.*, USER.username, USER.sex, USER.address FROM orders, USER WHERE orders.user_id = user.id </select> </mapper>

2.2.4mapper.java

public interface OrdersCustomMapper {
    //查詢訂單,關聯查詢使用者資訊
    public List<OrdersCustom> findOrdersUser() throws Exception;
}

2.2.5測試程式

  @Test
    public void findOrdersUserTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        OrdersCustomMapper ordersCustomMapper=sqlSession.getMapper(OrdersCustomMapper.class);
        List<OrdersCustom> list=ordersCustomMapper.findOrdersUser();
        System.out.println(list);
        sqlSession.close();
    }

2.3方法二:resultMap

2.3.1sql語句

同resultType實現的sql

2.3.2使用resultMap對映的思路

使用resultMap將查詢結果中的訂單資訊對映到Orders物件中,在Orders類中新增User屬性,將關聯查詢出來的使用者資訊對映到orders物件中的user屬性中。

2.3.3需要orders類中新增user屬性

2.3.4mapper.xml

2.3.4.1定義resultMap

    <!--訂單關聯查詢使用者的resultMap
        將整個查詢的結果對映到oanna.yan.mybatis.entity.Orders中
      -->
    <resultMap type="joanna.yan.mybatis.entity.Orders" id="OrdersUserResultMap">
        <!-- 1.配置對映的訂單資訊  -->
        <!-- id:指定查詢列中的唯一標識,訂單資訊中的唯一標識,如果有多個列組成唯一標識,配置多個id
             column:訂單資訊中的唯一標識列
             property:訂單資訊中的唯一標識列所對映到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"/>
        
        <!-- 2.配置對映的關聯的使用者資訊  -->
        <!-- association:用於對映關聯查詢單個物件的資訊
             property:要將關聯查詢的使用者資訊對映到Orders類中的哪個屬性
         -->
        <association property="user" javaType="joanna.yan.mybatis.entity.User">
            <!-- 關聯查詢使用者的唯一標識
                 column:指定唯一標識使用者資訊的列
                 property:對映到user的哪個屬性
              -->
            <id column="user_id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="address" property="sex"/>
        </association>
    </resultMap>

2.3.4.2定義statement定義

    <!--查詢訂單,關聯查詢使用者資訊,使用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.3.4.3mapper.java

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

2.3.4.4測試程式

    @Test
    public void findOrdersUserResultMapTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        OrdersCustomMapper ordersCustomMapper=sqlSession.getMapper(OrdersCustomMapper.class);
        List<Orders> list=ordersCustomMapper.findOrdersUserResultMap();
        System.out.println(list);
        sqlSession.close();
    }

2.4 resultType和resultMap實現一對一查詢小結

實現一對一查詢:

resultType:使用resultType實現較為簡單,如果pojo中沒有包括查詢出來的列名,需要增加列名對應的屬性,即可完成對映。

如果沒有查詢結果的特殊要求,建議使用resultType。

resultMap:需要單獨定義resultMap,實現有點麻煩,如果對查詢結果又特殊的要求,使用resultMap可以完成將關聯查詢對映pojo的屬性中。

resultMap可以實現延遲載入,resultType無法實現延遲載入。

3.一對多查詢

3.1需求

查詢訂單及訂單明細的資訊

3.2sql語句

確定主查詢表:訂單表

確定關聯查詢表:訂單明細表

在一對一查詢基礎上新增訂單明細表關聯即可。

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 orderdetail.orders_id=orders.id

3.3分析

使用resultType將上邊的查詢結果對映到pojo中,訂單資訊的就會重複。

要求:

對orders的對映不能出現重複記錄。

解決:

在Orders.java類中新增List<OrderDetail> orderDetails屬性。

最終會將訂單資訊對映到Orders中,訂單所對應的訂單明細對映到orders中的orderDetails屬性中。

對映成的orders記錄數為兩條(orders資訊不重複)

每個orders中的orderDetails屬性儲存了該訂單所對應的訂單明細。

 3.4在Orders類中新增list訂單明細屬性

3.5定義resultMap 

    <!--訂單及訂單明細的resultMap
        使用extends繼承,就不需要再配置訂單資訊和使用者資訊的映射了
      -->
    <resultMap type="joanna.yan.mybatis.entity.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap">
        <!-- 1.配置對映的訂單資訊  -->
        <!-- 2.配置對映的關聯的使用者資訊  -->
        <!-- 使用extends繼承,就不需要再配置訂單資訊和使用者資訊的映射了 -->
        <!-- 3.配置對映的訂單明細資訊  -->
        <!-- 訂單明細資訊
             一個訂單關聯查詢出了多條明細,要使用collection進行對映
             collection:對關聯查詢到的多條記錄對映到集合物件中
             property:將關聯查詢到多條記錄對映到joanna.yan.mybatis.entity.Orders中的哪個屬性
              ofType:指定對映到list集合屬性中pojo的型別
         -->
        <collection property="orderdetails" ofType="joanna.yan.mybatis.entity.Orderdetail">
            <!-- id:訂單明細的唯一標識
                 property:要講訂單明細的唯一標識對映到joanna.yan.mybatis.entity.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>

3.6mapper.xml

    <!-- 查詢訂單,關聯查詢使用者及訂單明細,使用resultMap -->
    <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 orderdetail.orders_id=orders.id
    </select>

3.7mapper.java

public interface OrdersCustomMapper {
    //查詢訂單,關聯查詢使用者資訊
    public List<OrdersCustom> findOrdersUser() throws Exception;
    //查詢訂單,關聯查詢使用者資訊,使用resultMap
    public List<Orders> findOrdersUserResultMap() throws Exception;
    //查詢訂單(關聯使用者)及訂單明細
    public List<Orders> findOrdersAndOrderDetailResultMap() throws Exception;
}

3.8測試程式

    @Test
    public void findOrdersAndOrderDetailResultMapTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        OrdersCustomMapper ordersCustomMapper=sqlSession.getMapper(OrdersCustomMapper.class);
        List<Orders> list=ordersCustomMapper.findOrdersAndOrderDetailResultMap();
        System.out.println(list);
        sqlSession.close();
    }

3.9小結

mybatis使用resultMap的collection對關聯查詢的多條記錄對映到有個list集合屬性中。

使用resultType實現:

將訂單明細對映到orders中的orderdetails中,需要自己處理,使用雙重迴圈遍歷,去掉重複記錄,將訂單明細放在ordertails中。

4.多對多查詢

4.1需求

查詢使用者及使用者購買的商品資訊。

4.2sql語句

查詢主表:使用者表

關聯表:由於使用者和商品沒有直接關聯,通過訂單和訂單明細進行關聯,所有關聯表:orders、orderdetail、items。

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 orderdetail.orders_id=orders.id AND orderdetail.items_id = items.id

4.3對映思路

將使用者資訊對映到user中。

在User類中新增訂單列表屬性List<Orders> orderslist,將使用者建立的訂單對映到orderslist;

在Orders中田間訂單明細列表屬性List<OrderDetail> orderdetails,將訂單的明細對映到orderdetails;

在OrderDetail中新增Items屬性,將訂單明細所對應的商品對映到Items。

4.4 mapper.xml

    <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 orderdetail.orders_id=orders.id AND orderdetail.items_id = items.id        
    </select>

4.5定義resultMap

    <!-- 查詢使用者及購買商品  -->
    <resultMap type="joanna.yan.mybatis.entity.User" id="UserAndItemsResultMap">
        <!-- 1.使用者資訊 -->
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <result column="address" property="address"/>
        <!-- 2.訂單資訊 -->
        <!-- 一個使用者對應多個訂單,使用collection對映 -->
        <collection property="ordersList" ofType="joanna.yan.mybatis.entity.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"/>
            <!-- 3.訂單明細  -->
            <!-- 一個訂單包括多個明細 -->
            <collection property="orderdetails" ofType="joanna.yan.mybatis.entity.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"/>
                <!-- 4.商品資訊  -->
                <!-- 一個訂單明細對應一個商品 -->
                <association property="items" javaType="joanna.yan.mybatis.entity.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>

4.6mapper.java

public interface OrdersCustomMapper {
    //查詢訂單,關聯查詢使用者資訊
    public List<OrdersCustom> findOrdersUser() throws Exception;
    //查詢訂單,關聯查詢使用者資訊,使用resultMap
    public List<Orders> findOrdersUserResultMap() throws Exception;
    //查詢訂單(關聯使用者)及訂單明細
    public List<Orders> findOrdersAndOrderDetailResultMap() throws Exception;
    //查詢使用者購買商品資訊
    public List<User> findUserAndItemsResultMap() throws Exception;
}

4.7測試程式

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

4.8多對多查詢總結

將查詢使用者購買的商品資訊明細清單(使用者名稱、使用者地址、購買商品名稱、購買商品時間、購買商品數量)

針對上面的需求就使用resultType將查詢到的記錄對映到一個擴充套件的pojo中,很簡單實現明細清單的功能。

一對多是多對多的特例,如下需求:

查詢使用者購買的商品資訊,使用者和商品的關係是多對多關係。

需求1:

查詢欄位:使用者賬號、使用者名稱稱、使用者性別、商品名稱、商品價格(最常見)

企業開發中常見明細列表,使用者購買商品明細列表,

使用resultType將上邊查詢列對映到pojo輸出。

需求2:

查詢欄位:使用者賬號、使用者名稱稱、購買商品數量、商品明細(滑鼠移上顯示明細)

使用resultMap將使用者購買的商品明細列表對映到user物件中。

總結:

使用resultMap是針對那些對查詢結果對映有特殊要求的功能,比如特殊要求對映成list中包含多個list。

 5.resultMap總結

resultType:

作用:將查詢結果按照sql列名pojo屬性一致性對映到pojo中。

場合:

  常見一些明細記錄的展示,比如使用者購買商品明細,將關聯查詢資訊全部展示在頁面時,此時可直接使用resultType將每一條記錄對映到pojo中,在前端頁面遍歷list(list中是pojo)即可。

resultMap:

  使用association和collection完成一對一和一對多高階對映(對結果又特殊的對映要求)。

association:

作用:將關聯查詢資訊對映到一個pojo物件中。

場合:

為了方便查詢關聯資訊可以使用association將關聯訂單資訊對映為使用者物件的pojo屬性中,比如:查詢訂單及關聯使用者資訊。

  使用resultType無法將查詢結果對映到pojo物件的pojo屬性中,根據對結果集查詢遍歷的需要選擇使用resultType還是resultMap。

collection:

作用:將關聯查詢資訊對映到一個list集合中。

場合:為了方便擦還行遍歷關聯資訊可以使用collection將關聯資訊對映到list集合中,比如:查詢使用者許可權範圍模組及模組下的選單,可使用collection將模組對映到模組list中,將選單列表對映到模組物件的選單list屬性中,這樣做冊目的也是方便對查詢結果集進行遍歷查詢。

  如果使用resultType無法將查詢結果對映到list集合中。

如果此文對您有幫助,微信打賞我一下吧~ 

相關推薦

Spring+SpringMVC+MyBatis深入學習搭建()——MyBatis關聯查詢

1.商品訂單資料模型 1.1資料模型分析思路 (1)每張表記錄的資料內容   分模組對每張表記錄的內容進行熟悉,相當於你學習系統需求(功能)的過程。 (2)每張表重要的欄位設定   非空欄位、外來鍵欄位 (3)資料庫級別表與表之間的關係   外來鍵關係 (4)表與表之間的業務關係   在分析表與表之間的

Spring+SpringMVC+MyBatis深入學習搭建(三)——MyBatis全局配置文件解析

保持 nbsp 延遲加載 行為 span 方便 doc ima actor 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6874672.html 前面有寫到Spring+SpringMVC+MyBatis深入學習及搭建(二)&

Spring+SpringMVC+MyBatis深入學習搭建(四)——MyBatis輸入映射與輸出映射

指定 2.6 face 生成 shm hashmap ace and 包裝 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6878529.html 前面有講到Spring+SpringMVC+MyBatis深入學習及搭建(三)&

Spring+SpringMVC+MyBatis深入學習搭建(八)——MyBatis查詢緩存

idt rtu void spring 寫到 查詢緩存 修改 針對 target 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6956206.html 前面講到:Spring+SpringMVC+MyBatis深入學習及搭建(

Spring+SpringMVC+MyBatis深入學習搭建(十)——MyBatis逆向工程

cat springmvc blank 不為 tex llc root from ssi 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6973266.html 前面講到:Spring+SpringMVC+MyBatis深入學習及

Spring+SpringMVC+MyBatis深入學習搭建(二)——MyBatis原始Dao開發和mapper代理開發

oid 方法註入 內部 需要 com 配置文件信息 lec lang auth 前面有寫到Spring+SpringMVC+MyBatis深入學習及搭建(一)——MyBatis的基礎知識。MybatisFirst中存在大量重復的代碼。這次簡化下代碼: 使用MyBatis開發

Spring+SpringMVC+MyBatis深入學習搭建(四)——MyBatis輸入映射與輸出映射(轉發同上)

resultmap 根據 except 就會 ash 用戶名 mvc html like 原地址:http://www.cnblogs.com/shanheyongmu/p/7121556.html 1. 輸入映射 通過parameterType指定輸入參數的類型,類型可

Spring+SpringMVC+MyBatis深入學習搭建(九)——MyBatisSpring整合

1.整合思路需要Spring通過單例方式管理SqlSessionFactory。Spring和MyBatis整合生成代理物件,使用SqlSessionFactory建立SqlSession。(Spring和MyBatis整合自動完成)持久層的mapper都需要由Spring進

Spring+SpringMVC+MyBatis深入學習搭建(八)——MyBatis查詢快取

1.什麼是查詢快取 mybatis提供查詢快取,用於減輕資料庫壓力,提高資料庫效能。 mybatis提供一級快取和二級快取。 一級快取是SqlSession級別的快取。在操作資料庫時需要構造sqlSession物件,在物件中有一個數據結構(HashMap)用於儲存快取資料。不同的sqlSession之間

Spring+SpringMVC+MyBatis深入學習搭建(七)——MyBatis延遲載入

1.什麼是延遲載入 resultMap可以實現高階對映(使用association、collection實現一對一及一對多對映),association、collection具備延遲載入功能。 需求: 如果查詢訂單並且關聯查詢使用者資訊。如果先查詢訂單資訊即可滿足要求,當我們需要查詢使用者資訊時再查下使用

Spring+SpringMVC+MyBatis深入學習搭建(四)——MyBatis輸入對映與輸出對映

1. 輸入對映 通過parameterType指定輸入引數的型別,型別可以是簡單型別、hashmap、pojo的包裝型別。 1.1 #{}與${} #{}實現的是向prepareStatement中的預處理語句設定引數值,sql語句中#{}表示一個佔位符即? <select id="findUse

Spring+SpringMVC+MyBatis深入學習搭建(三)——MyBatis全域性配置檔案解析

MyBatis的全域性配置檔案SqlMapConfig.xml,配置內容和順序如下: properties(屬性) setting(全域性配置引數) typeAliases(類名別名) typeHandlers(類名處理器) objectFactory(物件工廠) plugins(外掛) environm

Spring+SpringMVC+MyBatis深入學習搭建(十一)——SpringMVC架構

框架 ppi spring框架 edit 不同的 com get request html 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6985816.html 前面講到:Spring+SpringMVC+MyBatis深入學習

Spring+SpringMVC+MyBatis深入學習搭建(十四)——SpringMVCMyBatis整合

文件拷貝 conf lips glib ide doc from ive body 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/7010363.html 前面講到:Spring+SpringMVC+MyBatis深入學習及搭建(

Spring+SpringMVC+MyBatis深入學習搭建(五)——動態sql

mybatis核心:對sql語句進行靈活操作,通過表示式進行判斷,對sql進行靈活拼接、組裝。 mybatis提供各種標籤方法實現動態拼接sql。 1. if&where 1.2 需求 使用者資訊綜合查詢列表和使用者資訊查詢列表總數這兩個statement的定義使用動態sql。 對查詢條件進行判斷

Spring+SpringMVC+MyBatis深入學習搭建】17.SpringMVC攔截器

1.攔截器定義 Spring Web MVC的處理器攔截器類似於Servlet開發中的過濾器Filter,用於對處理器進行預處理和後處理。 定義攔截器,實現HandlerInterceptor介面。介面中提供三個方法。 package joanna.yan.ssm.interceptor; imp

spring深入學習(十) IOC 之parentBeanFactory 與依賴處理

繼上篇部落格 【死磕 Spring】—– 載入 bean 之 快取中獲取單例 bean,如果從單例快取中沒有獲取到單例 bean,則說明兩種情況: 該 bean 的 scope 不是 singleton 該 bean 的 scope 是 singleton ,但是沒有初始化

Redis深入學習筆記()Redis內存分配

swa 如果 利用 技術分享 拷貝 back width byte hat Redis的高效可以說是輕量級的epoll模型和基於內存的讀寫共同組成的,所以內存的使用就至關重要,本篇主要介紹Redis的內存分配原理。 獲取內存信息命令:info memory used_me

多執行緒深入學習面試解決思路

課程目標 執行緒與程序區別 為什麼要使用多執行緒? 多執行緒應用場景? 多執行緒建立方式 獲取執行緒物件以及名稱 守護執行緒 多執行緒執行狀態 join()方法作用 多執行緒分批處理資料 作業題 面試題 備註單詞 執行緒與程序區別

Dubbo服務治理框架深入學習面試題

  Dubbo概述 Dubbo的背景 隨著網際網路的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分散式服務架構以及流動計算架構勢在必行,亟需一個治理系統確保架構有條不紊的演進。  單一應用架構 當網站流量很小時,只需