文章出處

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集合中。


文章列表


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

    IT工程師數位筆記本

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