一、數據模型分析思路:
1、每張表記錄的數據內容
分模塊對每張表記錄的內容進行熟悉,相當於你學習系統需求(功能)的過程。
用戶表user:記錄了購買商品的用戶信息
訂單表orders:記錄了用戶所創建的訂單(即購買商品的訂單)
訂單明細表orderdetails:記錄了訂單的詳細信息即購買商品的信息
商品表items:記錄了商品的詳細信息
2、每張表重要的字段設置
非空字段、外鍵字段
3、數據庫級別表與表之間的關係
外鍵關係
4、表與表之間的業務關係
在分析表與表之間的業務關係時一定要建立在某個業務意義基礎上去分析。
1) 先分析數據庫級別之間有關係的表之間的業務關係:
A)user和orders:
user->orders:一個用戶可創建多個訂單,一對多;
orders->user 一個訂單隻由一個用戶創建,一對一;
B)orders和orderdetail:
orders->orderdetail:一個訂單可包括多個訂單明細,因爲一個訂單可購買多個商品,每個商品的購買信息在orderdetail記錄中,一對多;
orderdetail->orders:一個訂單隻能明細只能包括在一個訂單中,一對一;
C)orderdetail和items:
orderdetail->items:一個訂單明細只對應一個商品,一對一;
items->orderdetail:一個商品可包括在多個訂單中,一對多;
2)再分析數據庫級別沒有關係的表之間是否有業務關係:
A)orders和items
二、一對一查詢
2.1 需求:
查詢訂單信息,關聯查詢創建訂單的用戶信息
2.2 sql語句怎麼寫
確定查詢的主表:訂單表
確定查詢的關聯表:用戶表
關聯查詢使用內連接,還是外連接?
由於orders表中有一個外鍵(user_id),通過外鍵關聯查詢用戶表只能查詢出一條記錄,可使用內連接。
SELECT
orders.*,
USER.username,
USER.sex,
USER.address
FROM
orders,
USER
WHERE orders.user_id=user.id
2.3兩種查詢方法
2.3.1resultType實現思路
1)將上邊的查詢結果映射到pojo中,pojo中必須包括所有查詢列名。
2)原始的Orders.java不能映射所有字段,需要創建新的pojo。創建一個pojo繼承包括查詢字段較多的po類。
2.3.2resultMap實現思路
使用resultMap將查詢結果中的訂單信息映射到Orders對象中,在Orders類中添加User屬性,將關聯查詢出來的用戶信息映射到orders對象中的user屬性中。
public class Orders{
privateInteger id;
privateInteger userId;
privateString number;
privateString createTime;
privateUser user;
}
訂單查詢關聯用戶的resultMap,將整個查詢的結果映射到cn.itcast.mybatis.po.Orders中,將整個查詢的結果映射到cn.itcast.mybatis.po.Orders中。
<resultMap type="cn.itcast.mybatis.po.Orders" id="OrderUserResultMap">
<!-- 配置映射的訂單信息 -->
<!-- id:指定查詢中的唯一標識,訂單信息中的唯一標識;如果有多個列組成唯一標識,配置多個id -->
<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" />
<!-- 配置映射的關聯用戶信息 -->
<!-- association:用於映射關聯查詢單個對象的信息 property:要將關聯查詢的用戶信息映射到Orders中哪個屬性 -->
<association property="user" javaType="cn.itcast.mybatis.po.User">
<!-- id:關聯查詢用戶的唯一標識 column:指定唯一標識用戶信息的列 javaType:映射到user的哪個屬性 -->
<id column="user_id" property="id" />
<result column="username" property="username" />
<result column="sex" property="sex" />
<result column="address" property="address" />
</association>
</resultMap>
2.4、一對一查詢總結
resultType:實現比較簡單,如果pojo中沒有包括查詢出來的列名,需要增加列名對應的屬性,即可完成映射。
resultMap:需要單獨定義resultMap,如果有對查詢結果有特殊的要求,使用resultMap可以完成將關聯查詢映射到pojo的屬性中。
resultType中不能通過對象映射,只能將對象的屬性全都定義到pojo中;resultMap可將對象直接定義到po中,然後通過映射實現。
resultMap可實現延遲加載,resultType不能。
三、一對多查詢
3.1需求:查詢訂單及訂單明細信息。
3.2 sql語句:
確定主查詢表:訂單表
確定關聯查詢表:訂單明細表
在一對一基礎上添加訂單明細表關聯即可。
如果直接使用resultType將上邊的查詢結果映射到pojo中,訂單信息就會重複。要求:對orders映射不能出現重複記錄。在orders.java類中添加List<orderDetail> orderDetails屬性,最終會將訂單信息映射到orders中,訂單所對應的訂單明細映射到orders中的orderDetails屬性中。
3.3實現思路
3.3.1 resultMap
mybatis使用resultMap的collection對關聯查詢的多條記錄映射到一個list集合屬性中。
訂單及訂單明細的resultMap,使用extends繼承,不用在配置訂單信息和用戶信息的映射。<resultMap type=”cn.itcast.mybatis.po.Orders” id=”OrdersAndOrderDetailResultMap” extends=”OrderUserResultMap”>
<!—訂單信息 -->
<!—用戶信息 -->
<!— 使用繼承不用再配置訂單信息和用戶信息的映射 -->
<!—訂單明細信息
一個訂單關聯查出了多條明細,要使用collection進行映射
collection:對關聯查詢到多條記錄映射到集合對象中
property:將關聯查詢到多條記錄映射到cn.itcast.mybatis.po.Orders哪個屬性
ofType:指定映射到list集合屬性中pojo的類型
-->
<collection property=”orderdetails” ofType=”cn.itcast.mybatis.po.Orderdetail”>
<id column=”orderdetail_id” property=”id”/>
<result column=”items_id” property=”itemsId”/>
</collection>
</resultMap>
3.3.2使用resultType實現:
將訂單明細映射到orders中的orderdetails中,需要自己關聯,使用雙重循環遍歷,去掉重複記錄,將訂單明細放到orderdetails中。
四、多對多查詢
4.1需求:查詢用戶及用戶所購買的商品信息
分析:
查詢主表:用戶表
關聯表:由於用戶和商品沒有直接關聯,通過訂單和訂單明細關聯,所有關聯表:orders、orderdetail、items
4.2 sql語句
4.3映射思路
要將用戶信息映射到user中,需要:
在User類中添加訂單列表屬性List<Order> ordersList,將用戶創建的訂單映射到orderslist;
在Orders中添加訂單明細屬性List<OrderDetail> ordersDetail,將訂單的明細映射到orderdetails;
在OrderDetail中添加items屬性,將訂單明細對應的商品映射到items。
代碼中注意嵌套關係即可:
<!—查詢用戶及購買的商品 -->
<resultMap ……>
<-- 用戶信息 -->
<collection>
……
<-- 訂單信息,一個用戶對應多個訂單,使用collection映射 -->
<collection>
……
<-- 訂單明細,一個訂單對應多個訂單明細 -->
<collection>
……
<-- 商品信息,一個訂單明細對應一個商品 -->
<association>
……
</association>
</collection>
</collection>
<collection>
</resultMap>
4.4多對多查詢總結
1)情形一:查詢用戶購買的商品信息明細清單(用戶名、用戶地址、購買商品名稱、購買商品時間、購買商品數量)
針對上邊的需求就使用resultType將查詢到的記錄映射到一個擴展的pojo中,很簡單實現明細清單的功能。
2)情形二:一對多查詢是多對多查詢的特例,如下需求:
查詢用戶購買的商品信息,用戶與商品的關係是多對多關係。
需求1:
查詢用戶購買商品明細;
查詢字段:用戶賬號、用戶名稱、用戶性別、商品名稱、商品價格
使用resultType將上邊查詢列映射到pojo輸出。
需求2:
查詢字段:用戶賬號、用戶名稱、購買商品數量、商品明細(鼠標移上去顯示明細)
使用resultMap將用戶購買的商品明細列表映射到user對象中。
3)總結
使用resultMap是針對那些對查詢結果有特殊要求的功能,比如特殊要求映射成list中包括多個list;使用resultType無法將查詢結果映射到pojo對象的pojo屬性中。到底是用resultType還是resultMap,是根據對結果集查詢遍歷的需要選擇。