天天看點

mybatis進階映射

總結的内容mapper代理開發,一對一,一對多,多對多的進階映射。

首先介紹一個小的demo,然後通過這個例子來說說下映射。

分析下一個商品訂單的項目。資料模型分析。

mybatis進階映射

對象就兩個 人,商品。大家看下業務關系,我直接就說映射了。

一對一查詢

查詢訂單資訊,關聯查詢建立訂單的使用者資訊,就是先差訂單資訊,根據訂單資訊,差建立訂單的使用者的資訊。

查詢的主表:訂單表   查詢的關聯表:使用者表。由于orders表中有一個外鍵(user_id),通過外鍵關聯查詢使用者表隻能查詢出一條記錄,可以使用内連結。

sql語句,查詢orders中所有資訊,使用者表中的username sex address等資訊。

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

resultType方法

1、建立pojo,将上邊sql查詢的結果映射到pojo中,pojo中必須包括所有查詢列名,原始的Orders.java不能映射全部字段,需要新建立的pojo,建立一個pojo繼承包括查詢字段較多的po類。

public class OrdersCustom extends Orders{
	
	//添加使用者屬性
	/*USER.username,
	  USER.sex,
	  USER.address */
	
	private String username;
	private String sex;
	private String address;
    .......

}           

2、mapper.xml

<!-- 查詢訂單關聯查詢使用者資訊 -->

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

3、mapper.java

//查詢訂單關聯查詢使用者資訊
public List<OrdersCustom> findOrdersUser()throws Exception;           

resultMap方法

使用resultMap映射的思路。使用resultMap将查詢結果中的訂單資訊映射到Orders對象中,在orders類中添加User屬性,将關聯查詢出來的使用者資訊映射到orders對象中的user屬性中。

1、需要在Orders類中添加user屬性。

//使用者資訊
private User user;           

2.1、定義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>           

2.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>           
//查詢訂單關聯查詢使用者使用resultMap
public List<Orders> findOrdersUserResultMap()throws Exception;           

總結,resultType和resultMap實作一對一。主要的差別就是mapper.xml。

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

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

resultMap可以實作延遲加載,resultType無法實作延遲加載。

一對多查詢

查詢訂單及訂單明細資訊,通過查詢訂單,根據訂單資訊差訂單明細資訊。

主查詢表:訂單表,關聯查詢表:訂單明細表。

分析:如果訂單表中的一條資訊對應的訂單明細表中有兩條資訊, 使用resultType将上邊的 查詢結果映射到pojo中,訂單資訊就會重複。

要求對orders映射不能重複出現,在orders.java類中添加List<orderDetail> orderDetails屬性。

最終會将訂單資訊映射到orders中,訂單所對應的訂單明細映射到orders中的orderDetails屬性中。每個orders中的orderDetails屬性存儲了該 訂單所對應的訂單明細。

1、在oders中添加list訂單明細屬性

//訂單明細
private List<Orderdetail> orderdetails;           

2.1、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 -->
	<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>           
//查詢訂單(關聯使用者)及訂單明細
public List<Orders>  findOrdersAndOrderDetailResultMap()throws Exception;           

多對多基本步驟上面的差不多。

映射思路

将使用者資訊映射到user中。

在user類中添加訂單清單屬性List<Orders> orderslist,将使用者建立的訂單映射到orderslist

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

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

<!-- 查詢使用者及購買的商品 -->
<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>