MyBatis 一對一,一對多,多對多


什么是一對一,一對多,多對多?

以用戶和訂單舉例,

一對一 : 一個訂單只屬於一個用戶 ==> 訂單對用戶是一對一關系

      一個用戶只能有一個訂單 ==> 用戶對訂單是一對一關系

一對多 : 一個用戶可以擁有多個訂單 ==> 用戶對訂單是一對多關系

多對多 : 一個訂單可以有多種商品,並且一種商品可以被多個訂單包含 ==> 商品和訂單是多對多關系

數據庫和實體(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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM