什么是一對一,一對多,多對多?
以用戶和訂單舉例,
一對一 : 一個訂單只屬於一個用戶 ==> 訂單對用戶是一對一關系
一個用戶只能有一個訂單 ==> 用戶對訂單是一對一關系
一對多 : 一個用戶可以擁有多個訂單 ==> 用戶對訂單是一對多關系
多對多 : 一個訂單可以有多種商品,並且一種商品可以被多個訂單包含 ==> 商品和訂單是多對多關系
數據庫和實體(POJO)的設定
user表
oders表
User類(省略geter&seter)
Oders類(省略geter&seter)
下面用實例講解一對一和一對多,只展示Mapper映射文件內容,Dao,Service,Controller層內容省略
一對一
一個訂單對應一個用戶,即一對一(訂單對用戶是一對一)
在POJO上的實現是,Orders類內包含一個User屬性
現在我們用訂單id來查詢訂單和對應用戶的數據(關聯查詢)
如果用resultType的寫法,myBatis就不能將查詢結果綁定到Orders的user對象內,如下圖,
運行后oders對象內的user屬性將為null,Oders類內定義的其他屬性可以正常賦值
為了解決這個問題,我們可以用resultMap來替代resultType
有兩種實現方法,一種是嵌套結果,一種是嵌套查詢
一.嵌套結果
<select id="getOrderAndUserByOrderId" resultMap="ordersAndUser"> SELECT * FROM orders o, user u WHERE o.user_id=u.id AND o.id=#{id} </select> <!-- 這是resultMap --> <resultMap type="com.jy.entity.Orders" id="ordersAndUser"> <id property="id" column="id"/> <result property="user_id" column="user_id"/> <!-- 這是映射 --> <association property="user" javaType="com.jy.entity.User"> <id property="id" column="id" /> <result property="username" column="username"/> <result property="password" column="password"/> <result property="realname" column="realname"/> </association> </resultMap>
<resultMap> :
type ==> Orders類的路徑
id ==> resultMap名
<association> :
property ==> Orders類內user屬性名
jayaType ==> user的類路徑
二.嵌套查詢
<select id="getOrderAndUserByOrderId" resultMap="ordersAndUser"> SELECT * FROM orders where id=#{id} </select> <resultMap type="com.jy.entity.Orders" id="ordersAndUser"> <id property="id" column="id"/> <result property="user_id" column="user_id"/> <!-- column是傳的參數, select是調用的查詢 --> <association property="user" column="user_id" select="getUserById"/> </resultMap> <select id="getUserById" resultType="user"> SELECT * FROM user WHERE id=#{user_id} </select>
<association> :
property ==> Oders類內的user屬性
column ==> 調用查詢時傳入的參數
select ==> 調用的查詢語句
通過以上的嵌套結果或嵌套查詢的方法,即可成功為Oders內的user屬性賦值!
一對多
一個用戶有多個訂單,即一對多(用戶對訂單是一對多)
<select id="getUserAndOrdersByUserId" resultMap="UserAndOrders"> SELECT u.id uid, u.username, u.password, u.realname, o.id, o.user_id FROM user u, orders o WHERE u.id=o.user_id AND u.id=#{id} </select> <resultMap type="com.jy.entity.User" id="UserAndOrders"> <id property="id" column="uid"/> <result property="username" column="username"/> <result property="password" column="password"/> <result property="realname" column="realname"/> <collection property="orders" ofType="com.jy.entity.Orders"> <id property="id" column="id"/> <result property="user_id" column="user_id"/> </collection> </resultMap>
<collection> :
property ==> User類中的orders屬性
ofType ==> Orders類路徑
注意!
訂單只能查詢到一條結果??
用戶和訂單的id值如果名字一樣的話,會發生沖突!這樣查詢結果中只會有一個訂單,查不到所有訂單!
解決辦法 : 在SQL文中給其中一個id起別名,然后在column屬性中輸入別名!!
多對多
使用中間表來操作,省略
總結
1.不管是一對一還是多對多,都要使用<resultMap> ,屬性有id 和type
2.一對一中,<resultMap>內要用<association>來映射復雜對象,屬性有 :
(property和javaType) ==> 嵌套結果
(property, column, select) ==> 嵌套查詢
3.一對多中,<resultMap>內要用<collection>來映射復雜對象,屬性有property和ofType
4.注意防范<resultMap>和<association>或<collection>中字段名沖突的問題!
f