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 預設延遲加載 |
-
為了實作一對一主要通過兩種方式 :嵌套查詢 和嵌套結果
嵌套查詢–>通過執行另外一條SQl映射語句來傳回預期輔助類型 會降低資料區性能
嵌套結果–>使用嵌套結果映射處理重複的聯合結果子集 -->減少複雜度,執行一條SQL語句 推薦使用
- 代碼塊 :
//代碼本地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
在一對一的基礎上
一個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>