一對一查詢
需求
查詢所有訂單信息今豆,關聯(lián)查詢下單用戶信息竣况。
SQL
select a.*,b.username,b.address
from orders a
left join user b on a.userid=b.id
主信息:訂單信息
從信息:用戶信息
方法
方法一:resultType
方法二:resultMap
使用resultMap進行結果映射珊豹,定義專門的resultMap用于映射一對一查詢結果惜姐。
- 創(chuàng)建擴展pojo
創(chuàng)建OrdersExt類(用于結果集分裝)竞帽,加入User屬性调违,因為一對一,這里使用單個User對象存儲瑰煎。
public class OrdersExt extends Order {
private User user;// 用戶對象
// get/set铺然。。酒甸。魄健。
}
- mapper.xml文件
<!-- 查詢訂單關聯(lián)用戶信息使用resultmap -->
<resultMap type="OrdersExt" id="ordersAndUserRstMap">
<id column="id" property="id"/>
<result column="userid" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 一對一關聯(lián)映射 -->
<!--
property:Order對象的user屬性
javaType:user屬性對應 的類型
association:表示進行一對一關聯(lián)查詢映射
-->
<association property="user" javaType="com.demo.mybatis.po.User">
<!-- column:user表的主鍵對應的列 property:user對象中id屬性-->
<id column="userid" property="id"/>
<result column="username" property="username"/>
<result column="address" property="address"/>
</association>
</resultMap>
property:Order對象的user屬性。
javaType:user屬性對應 的類型插勤。
association:表示進行一對一關聯(lián)查詢映射沽瘦。
總結
使用resultMap進行結果映射時,具體是使用association完成關聯(lián)查詢的映射农尖,將關聯(lián)查詢信息映射到pojo對象中析恋。
一對多查詢
需求
查詢所有用戶信息及用戶關聯(lián)的訂單信息。
SQL
SELECT
a.*,
b.id oid,
b.number,
b.createtime,
b.note
FROM user a
LEFT JOIN orders b ON a.id = b.userid
主信息:用戶信息
從信息:訂單信息
分析
在一對多的使用中盛卡,只能使用resultMap進行結果映射
- 一對多關聯(lián)查詢時助隧,sql查詢出來的結果可能有多條,但映射對象只有一個滑沧。
- resultType的映射是一條記錄映射為一個對象并村。
- resultMap完成映射是以【主信息】為主對象,【從信息】映射為集合或對象滓技,然后封裝到主對象中橘霎。
方法
- 修改pojo類,添加private List<Order> orders。
@Data
public class User(){
private List<Order> orders;// 訂單信息
private String userid;
private String username;
private String address;
...
}
- mapper.xml
<resultMap type="user" id="userAndOrderRstMap">
<!-- 用戶信息映射 -->
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<!-- 一對多關聯(lián)映射
property:User對象的orders屬性
ofType:用來指定映射到List或集合中的實體類型殖属,泛型中的約束類型。
collection :表示進行一對多關聯(lián)查詢映射
-->
<collection property="orders" ofType="com.demo.mybatis.po.Order">
<id property="id" column="oid"/>
<result property="userId" column="id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</collection>
</resultMap>
Collection標簽:定義了一對多關聯(lián)的結果映射瓦盛。
property="orders":關聯(lián)查詢的結果集存儲在User對象的上哪個屬性洗显。
ofType="com.demo.mybatis.po.Order":指定關聯(lián)查詢的結果集中的對象類型即List中的對象類型。此處可以使用別名原环,也可以使用全限定名挠唆。
延遲加載
是什么?
- MyBatis延遲加載也稱懶加載,是指進行關聯(lián)查詢時嘱吗,按照設置延遲規(guī)則推遲對關聯(lián)對象的select查詢玄组,可減輕數(shù)據(jù)庫壓力滔驾。
- 必須通過resultMap中的association和collection子標簽才能演示成功。
- MyBatis的延遲加載也被稱為嵌套查詢俄讹,對應還有嵌套結果的概念哆致。
- MyBtis的延遲加載只針對關聯(lián)查詢對象,主加載對象都是直接查詢結果患膛。
分類
MyBatis根據(jù)關聯(lián)對象查詢的select的語句的執(zhí)行時機摊阀,分為三種類型:直接加載、侵入式加載和深度延遲加載踪蹬。
延遲加載策略需要在Mybatis的全局配置文件中胞此,通過標簽進行設置。
直接加載
執(zhí)行完對主加載對象的select語句跃捣,馬上執(zhí)行對關聯(lián)對象的select查詢漱牵。
<settings>
<!-- 延遲加載總開關 -->
<setting name="lazyLoadingEnabled" value="false"/>
</settings>
侵入式加載
執(zhí)行對主加載對象的select查詢時,不會執(zhí)行對關聯(lián)對象的查詢疚漆。但當要訪問主加載對象的某個屬性(該屬性不是關聯(lián)對象的屬性)時酣胀,就會馬上執(zhí)行關聯(lián)對象的select查詢。
<settings>
<!-- 延遲加載總開關 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入式延遲加載開關 -->
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
深度延遲加載
執(zhí)行對主加載對象的select查詢時愿卸,不會執(zhí)行對關聯(lián)對象的查詢灵临。當要訪問主加載對象的詳情時也不會執(zhí)行對關聯(lián)對象的查詢。當訪問到關聯(lián)對象的詳情時才執(zhí)行對關聯(lián)對象的查詢趴荸。
<settings>
<!-- 延遲加載總開關 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入式延遲加載開關 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
N+1問題
- 深度延遲加載的使用會提升性能儒溉。
- 如果延遲加載的表數(shù)據(jù)太多,就會產(chǎn)生N+1問題发钝,主信息加載一次算一次顿涣,而從信息是會根據(jù)主信息傳遞過來的條件,去查詢從表多次酝豪。