mybatis之嵌套查詢和嵌套結(jié)果有哪些區(qū)別
mybatis嵌套查詢和嵌套結(jié)果有啥區(qū)別
嵌套查詢的弊端:即嵌套查詢的N+1問題
盡管嵌套查詢大量的簡化了存在關(guān)聯(lián)關(guān)系的查詢,但它的弊端也比較明顯:即所謂的N+1問題。關(guān)聯(lián)的嵌套查詢顯示得到一個結(jié)果集,然后根據(jù)這個結(jié)果集的每一條記錄進(jìn)行關(guān)聯(lián)查詢。
現(xiàn)在假設(shè)嵌套查詢就一個(即resultMap內(nèi)部就一個association標(biāo)簽),現(xiàn)查詢的結(jié)果集返回條數(shù)為N,那么關(guān)聯(lián)查詢語句將會被執(zhí)行N次,加上自身返回結(jié)果集查詢1次,共需要訪問數(shù)據(jù)庫N+1次。
如果N比較大的話,這樣的數(shù)據(jù)庫訪問消耗是非常大的!所以使用這種嵌套語句查詢的使用者一定要考慮慎重考慮,確保N值不會很大。
嵌套結(jié)果查詢
嵌套語句的查詢會導(dǎo)致數(shù)據(jù)庫訪問次數(shù)不定,進(jìn)而有可能影響到性能。
Mybatis還支持一種嵌套結(jié)果的查詢:即對于一對多,多對多,多對一的情況的查詢,Mybatis通過聯(lián)合查詢,將結(jié)果從數(shù)據(jù)庫內(nèi)一次性查出來,然后根據(jù)其一對多,多對一,多對多的關(guān)系和ResultMap中的配置,進(jìn)行結(jié)果的轉(zhuǎn)換,構(gòu)建需要的對象。
探索嵌套查詢和嵌套結(jié)果這對孿生子的秘密!?。?/h2>
MyBatis在映射文件中加載關(guān)聯(lián)關(guān)系對象主要通過兩種方式:嵌套查詢和嵌套結(jié)果。
嵌套查詢是指通過執(zhí)行另外一條SQL映射語句來返回預(yù)期的復(fù)雜類型;
嵌套結(jié)果是使用嵌套結(jié)果映射來處理重復(fù)的聯(lián)合結(jié)果的子集。開發(fā)人員可以使用上述任意一種方式實現(xiàn)對關(guān)聯(lián)關(guān)系的加載。
這兩者之間有什么聯(lián)系?
如何理解這些區(qū)別呢?????
咱們直接代碼來說話。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zsj.mapper.PersonMapper"> <!-- 嵌套查詢:通過執(zhí)行另外一條SQL映射語句來返回預(yù)期的特殊類型 --> <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.zsj.mapper.IdCardMapper.findCodeById" /> </resultMap> <!-- 嵌套結(jié)果:使用嵌套結(jié)果映射來處理重復(fù)的聯(lián)合結(jié)果的子集 --> <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> </mapper>
輸出結(jié)果:
嵌套查詢:
嵌套結(jié)果:
從上面的調(diào)試日志可以看出,兩者不同方式的查詢SQL語句的難易程度和語句數(shù)。并且從代碼中不難看出兩者在編寫SQL語句代碼方面不同,嵌套查詢相較于嵌套結(jié)果來說,編寫較簡單?。。?/p>
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
參考文獻(xiàn):MyBatis官方文檔
相關(guān)文章
SpringBoot?整合?Elasticsearch?實現(xiàn)海量級數(shù)據(jù)搜索功能
這篇文章主要介紹了SpringBoot?整合?Elasticsearch?實現(xiàn)海量級數(shù)據(jù)搜索,本文主要圍繞?SpringBoot?整合?ElasticSearch?接受數(shù)據(jù)的插入和搜索使用技巧,在實際的使用過程中,版本號尤其的重要,不同版本的?es,對應(yīng)的?api?是不一樣,需要的朋友可以參考下2022-07-07關(guān)于SpringSecurity?Context?中獲取和更改當(dāng)前用戶信息的問題
SpringSecurityContext在異步線程中無法獲取用戶信息,因其與請求線程綁定;此外,用戶信息更新后跳轉(zhuǎn)頁面時,身份會被降級為匿名,導(dǎo)致信息無法及時同步,本文給大家介紹SpringSecurity?Context?中獲取和更改當(dāng)前用戶信息的問題,感興趣的朋友一起看看吧2024-09-09springboot創(chuàng)建監(jiān)聽和處理事件的操作方法
這篇文章主要介紹了springboot創(chuàng)建監(jiān)聽和處理事件的操作方法,使用Spring Boot的事件機制來監(jiān)聽和處理事件有多種優(yōu)勢,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧2024-07-07ElasticSearch之索引模板滾動索引實現(xiàn)詳解
這篇文章主要為大家介紹了ElasticSearch之索引模板滾動索引實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04深入理解JavaWeb中過濾器與監(jiān)聽器的應(yīng)用
這篇文章主要介紹了JavaWeb中過濾器與監(jiān)聽器的應(yīng)用,過濾器能夠?qū)ζヅ涞恼埱蟮竭_(dá)目標(biāo)之前或返回響應(yīng)之后增加一些處理代碼,監(jiān)聽器是一個接口內(nèi)容由我們實現(xiàn),會在特定時間被調(diào)用,感興趣想要詳細(xì)了解可以參考下文2023-05-05