標籤:

Mybatis4:訂單商品模型分析+高級映射

前面我們已經介紹了Mybatis的基本思路以及操作。

接下來介紹實際應用中訂單商品的模型是怎麼設計的。

數據模型分析思路

1、每張表記錄的數據內容

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

2、每張表重要的欄位設置

非空欄位、外鍵欄位

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

外鍵關係

4、表與表之間的業務關係

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

用戶表user:

記錄了購買商品的用戶信息

訂單表:orders

記錄了用戶所創建的訂單(購買商品的訂單)

訂單明細表:orderdetail:

記錄了訂單的詳細信息即購買商品的信息

商品表:items

記錄了商品信息

表與表之間的業務關係:

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

先分析數據級別之間有關係的表之間的業務關係:

usre和orders:

user---->orders:一個用戶可以創建多個訂單,一對多

orders--->user:一個訂單只由一個用戶創建,一對一

orders和orderdetail:

orders---》orderdetail:一個訂單可以包括 多個訂單明細,因為一個訂單可以購買多個商品,每個商品的購買信息在orderdetail記錄,一對多關係

orderdetail--> orders:一個訂單明細只能包括在一個訂單中,一對一

orderdetail和itesm:

orderdetail---》itesms:一個訂單明細只對應一個商品信息,一對一

items--> orderdetail:一個商品可以包括在多個訂單明細 ,一對多

再分析資料庫級別沒有關係的表之間是否有業務關係:

orders和items:

orders和items之間可以通過orderdetail表建立 關係。

----------------------------------------------------------------------------------高級映射 一對一查詢 使用resultType

需求:查詢訂單信息,關聯查詢用戶信息

1.確定sql語句

確定查詢的主表:訂單表

確定查詢的關聯表:用戶表

關聯查詢使用內鏈接?還是外鏈接?

由於orders表中有一個外鍵(user_id),通過外鍵關聯查詢用戶表只能查詢出一條記錄,可以使用內鏈接。

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

2.創建POJO

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

原始的Orders.java不能映射全部欄位,需要新創建的pojo。因為除了訂單信息還會映射出用戶信息。

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

3.創建OrdersMapperCustom.xml和OrdersMapperCustom介面

介面:

public interface OrderMapperCustom { public List<OrdersCustom> findOrderUser();}

(注意輸入輸出,地址,函數名之間的一一對應)

xml:

<mapper namespace="cn.itcast.mysql.mapper.OrderMapperCustom"> <select id="findOrderUser" resultType="cn.itcast.mybatis.po.OrdersCustom"> SELECT orders.*, USER.username, USER.sex, USER.address FROM orders, USER WHERE orders.user_id = user.id </select></mapper>

4.在sqlMapConfig中配置該mapper

直接一個包的配置

<mappers > <package name="cn.itcast.mysql.mapper"/> </mappers>

5.通過SqlSessionFactory獲取SqlSession,然後獲取Mapper代理對象,調用方法即可。

----------------------------------------------------------------------------------

高級映射 一對一查詢 使用resultMap

1.確定sql語句

同上resultType

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

2.創建pojo

3.配置mapper.xml

定義resultMap

<!-- 訂單查詢關聯用戶的resultMap 將整個查詢的結果映射到cn.itcast.mybatis.po.Orders中 --> <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap"> <!-- 配置映射的訂單信息 --> <!-- 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/> <!-- 配置映射的關聯的用戶信息 --> <!-- 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>

定義statement

關鍵字使用resultMap

然後在sqlMapConfig中配置。剩餘步驟同上

resultMap和resultType在一對一中的映射區別:

實現一對一查詢:

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

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

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

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

----------------------------------------------------------------------------------

高級映射 一對多查詢 使用resultMap

確定主查詢表:訂單表

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

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

SELECT orders.*, USER.username, USER.sex, USER.address,orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, orderdetail.orders_idFROM orders, USER, orderdetailWHERE orders.user_id = user.id AND orders.id

使用resultType將上邊的 查詢結果映射到pojo中,訂單信息的就是重複。

處理稍微複雜。所以一對多建議使用resultMap

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

使用resultType實現:

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

resultMap定義pojo,然後類似一對一,去實現應的mapper.xml即可。

我們來看看resultMap的定義(重要)

<!-- 訂單及訂單明細的resultMap 使用extends繼承,不用在中配置訂單信息和用戶信息的映射 --> <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap"> <!-- 訂單信息 --> <!-- 用戶信息 --> <!-- 使用extends繼承,不用在中配置訂單信息和用戶信息的映射 --> <!-- 訂單明細信息 一個訂單關聯查詢出了多條明細,要使用collection進行映射 collection:對關聯查詢到多條記錄映射到集合對象中 property:將關聯查詢到多條記錄映射到cn.itcast.mybatis.po.Orders哪個屬性 ofType:指定映射到list集合屬性中pojo的類型 --> <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"> <!-- id:訂單明細唯 一標識 property:要將訂單明細的唯 一標識 映射到cn.itcast.mybatis.po.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>

----------------------------------------------------------------------------------

高級映射 多對多查詢 使用resultMap

1.1 需求

查詢用戶及用戶購買商品信息。

1.2 sql語句

根據表與表之間的關係書寫

查詢主表是:用戶表

關聯表:由於用戶和商品沒有直接關聯,通過訂單和訂單明細進行關聯,所以關聯表:

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_priceFROM orders, USER, orderdetail, itemsWHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id = items.id

1.3映射思路

創建類,然後定義屬性,同上

將用戶信息映射到user中。

在user類中添加訂單列表屬性List<Orders> orderslist,將用戶創建的訂單映射到orderslist

在Orders中添加訂單明細列表屬性List<OrderDetail>orderdetials,將訂單的明細映射到orderdetials

在OrderDetail中添加Items屬性,將訂單明細所對應的商品映射到Items

1.4.mapper.xml

配置resultMap

注意結構書寫。

一個用戶對應多個訂單,一個訂單對應多個訂單信息,一個訂單信息對應一個商品

<!-- 查詢用戶及購買的商品 --> <resultMap type="cn.itcast.mybatis.po.User" id="UserAndItemsResultMap"> <!-- 用戶信息 --> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> <!-- 訂單信息 一個用戶對應多個訂單,使用collection映射 --> <collection property="ordersList" ofType="cn.itcast.mybatis.po.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"/> <!-- 訂單明細 一個訂單包括 多個明細 --> <collection property="orderdetails" ofType="cn.itcast.mybatis.po.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"/> <!-- 商品信息 一個訂單明細對應一個商品 --> <association property="items" javaType="cn.itcast.mybatis.po.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>

1.5mapper.java

多對多查詢總結

將查詢用戶購買的商品信息明細清單,(用戶名、用戶地址、購買商品名稱、購買商品時間、購買商品數量)

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

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

查詢用戶購買的商品信息,用戶和商品的關係是多對多關係。

需求1:

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

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

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

需求2:

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

使用resultMap將用戶購買的商品明細列表映射到user對象中。

總結:

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


推薦閱讀:

Mybatis1:基礎

TAG:MyBatis |