天天看點

MyBatis的關聯映射映射的關系分類

MyBatis的關聯映射

  • 映射的關系分類
    • 一對一
    • 一對多
    • 多對多

映射的關系分類

一對一,一對多、多對多

一對一

本類中定義對方的類型的對象,表1.2

通過resultMap元素裡的 association來處理

association>:配置及一下屬性

                                                    表1.1

屬性名 作用
property 映射到實體對象屬性,與表字段一一對應 -->private IdCard card// property=“card”
column 指定表對應字段 -->column=“card_id” 資料庫的真實字段
javaType 映射到實體對象屬性 -->javaType=“IdCard” 映射
select 引入嵌套的子SQL語句、關聯嵌套的映射查詢 -->select=“com.itheima.mapper.IdCardMapper.findCodeById” 引入另外一條
fetchType 關聯是否啟用延遲加載 有lazy 和eage 預設延遲加載
  1. 為了實作一對一主要通過兩種方式 :嵌套查詢 和嵌套結果

    嵌套查詢–>通過執行另外一條SQl映射語句來傳回預期輔助類型 會降低資料區性能

    嵌套結果–>使用嵌套結果映射處理重複的聯合結果子集 -->減少複雜度,執行一條SQL語句 推薦使用

  2. 代碼塊 :
//代碼本地chapter09嵌套查詢
<select id="findPersonById" parameterType="Integer" 
                                      resultMap="IdCardWithPersonResult">
		SELECT * from tb_person where id=#{id}
	</select>

	<resultMap type="Person" id="IdCardWithPersonResult">
		<id property="id" column="id" />
		<result property="name" column="name" />
		<result property="age" column="age" />
		<result property="sex" column="sex" />
		<!-- 一對一:association使用select屬性引入另外一條SQL語句 -->
		<association property="card" column="card_id" javaType="IdCard"
			select="com.itheima.mapper.IdCardMapper.findCodeById" />
	</resultMap>
	到資料庫的真實語句: SELECT * from tb_person where id=? //惰性加載先執行第一條 然後第二條 嵌套關聯輸出
			    SELECT * from tb_idcard where id
	//下面是嵌套結果,就是子查詢
	嵌套結果--> <select id="findPersonById2" parameterType="Integer" 
	                                   resultMap="IdCardWithPersonResult2">
	    SELECT p.*,idcard.code
	    from tb_person p,tb_idcard idcard
	    where p.card_id=idcard.id 
	    and p.id= #{id}
	</select>
	
	<resultMap type="Person" id="IdCardWithPersonResult2">
	    <id property="id" column="id" />
	    <result property="name" column="name" />
	    <result property="age" column="age" />
	    <result property="sex" column="sex" />
	    <association property="card" javaType="IdCard">
	        <id property="id" column="card_id" />
	        <result property="code" column="code" />
	    </association>
	</resultMap>
	到資料庫的真實語句:SELECT p.*,idcard.code from tb_person p,tb_idcard idcard where //p,idcard 是表的别名
				p.card_id=idcard.id and p.id= 1;
           

一對多

表1.2
MyBatis的關聯映射映射的關系分類

在一對一的基礎上

一個A類中對應多個B類型的情況,表1.2

通過 resultMap 元素裡的 collection 來處理

collection:配置及一下屬性

ofType:與javaType 映射到實體對象屬性–>用于實體對象屬性包含的元素

其他子元素與 association子 元素相同

見上表1.1
<!-- namespace表示命名空間 -->
<mapper namespace="com.itheima.mapper.UserMapper">
	<!-- 一對多:檢視某一使用者及其關聯的訂單資訊 
	      注意:當關聯查詢出的列名相同,則需要使用别名區分 -->
	<select id="findUserWithOrders" parameterType="Integer" 
						   resultMap="UserWithOrdersResult">
		SELECT u.*,o.id as orders_id,o.number 
		from tb_user u,tb_orders o 
		WHERE u.id=o.user_id 
         and u.id=#{id}
	</select>
	
	<resultMap type="User" id="UserWithOrdersResult">
		<id property="id" column="id"/>
		<result property="username" column="username"/>
		<result property="address" column="address"/>
		<!-- 一對多關聯映射:collection 
			ofType表示屬性集合中元素的類型,List<Orders>屬性即Orders類 -->
		<collection property="ordersList" ofType="Orders">
			<id property="id" column="orders_id"/>
			<result property="number" column="number"/>
		</collection>
	</resultMap>
</mapper>
           

測試類

@Test
    public void findUserTest() {
        // 1、通過工具類生成SqlSession對象
        SqlSession session = MybatisUtils.getSession();
        // 2、查詢id為1的使用者資訊
        User user = session.selectOne("com.itheima.mapper."
                                + "UserMapper.findUserWithOrders", 1);
        // 3、輸出查詢結果資訊
        System.out.println(user);
        // 4、關閉SqlSession
        session.close();
    }

           

多對多

在一對多的基礎上

在A類型中定義B類型的集合,在B類型中定義A類型的集合,表1.2

也是通過 resultMap 元素裡的 collection 來處理 、

注意中間表不需要在實體屬性中寫入中間表,在配置XML嵌套結果的SQL語句中展現。

<mapper namespace="com.itheima.mapper.OrdersMapper">
	<!-- 多對多嵌套結果查詢:查詢某訂單及其關聯的商品詳情 -->
	<select id="findOrdersWithPorduct2" parameterType="Integer" 
	         resultMap="OrdersWithPorductResult2">
	    select o.*,p.id as pid,p.name,p.price
	    from tb_orders o,tb_product p,tb_ordersitem  oi
	    WHERE oi.orders_id=o.id 
	    and oi.product_id=p.id 
	    and o.id=#{id}
	</select>
	<!-- 自定義手動映射類型 -->
	<resultMap type="Orders" id="OrdersWithPorductResult2">
	    <id property="id" column="id" />
	    <result property="number" column="number" />
	    <!-- 多對多關聯映射:collection -->
	    <collection property="productList" ofType="Product">
	        <id property="id" column="pid" />
	        <result property="name" column="name" />
	        <result property="price" column="price" />
	    </collection>
	</resultMap>
	//中間表tb_ordersitem 商品清單表
</mapper>