新聞中心
今天了不起來說說這個關(guān)于 Mybatis ,為什么要說 Mybatis 呢?因?yàn)楝F(xiàn)在面試的時候,除了那些最基礎(chǔ)的,比如如何防止 SQL 注入,以及 Mybatis 的一級緩存,二級緩存之后,還有一些其他的問題,比如 Mybatis 的延遲加載,并且需要說一下延遲加載的使用場景。今天了不起就來給大家說一下這個延遲加載到底是怎么回事,以及延遲加載的使用場景。

成都創(chuàng)新互聯(lián)公司專注于郾城企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站,商城網(wǎng)站制作。郾城網(wǎng)站建設(shè)公司,為郾城等地區(qū)提供建站服務(wù)。全流程按需求定制制作,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)
什么是延遲加載?
延遲加載也稱為懶加載、惰性加載,使用延遲加載可以提高程序的運(yùn)行效率,針對數(shù)據(jù)持久層的操作,在某些特定查詢的情況下去訪問特定的數(shù)據(jù)庫,在其他情況下可以不訪問某些數(shù)據(jù)表,盡量減少 SQL 的執(zhí)行,從而達(dá)到提高速度的目的,是對數(shù)據(jù)庫操作的一種優(yōu)化。
什么情況下會出現(xiàn)延遲加載的情況
我們來舉個簡單的例子
在一對多中,當(dāng)我們有一個用戶,它有個100個訂單 在查詢用戶的時候,要不要把關(guān)聯(lián)的訂單查出來? 在查詢訂單的時候,要不要把關(guān)聯(lián)的用戶查出來?
那這個時候,答案就很清晰了,肯定要查出來的,但是,是我在需要的地方。
在查詢用戶時,用戶下的訂單應(yīng)該是,什么時候用,什么時候查詢。
在查詢訂單時,訂單所屬的用戶信息應(yīng)該是隨著訂單一起查詢出來
這個時候我們就會用到延遲加載了,我用的時候,我們就查詢,我們不用的時候,我們就不再繼續(xù)的進(jìn)行查詢了。
注意:延遲加載的應(yīng)用要求:關(guān)聯(lián)對象的查詢與主加載對象的查詢必須是分別進(jìn)行的select語句,不能是使用多表連接所進(jìn)行的select查詢。
延遲加載分類
其實(shí)延遲加載也是有區(qū)分對的,而這個區(qū)分就是,全局的延遲加載和局部的延遲加載。
全局延遲加載
全局延遲加載的實(shí)現(xiàn),實(shí)際上是通過修改配置文件來進(jìn)行實(shí)現(xiàn)的,只要改了對應(yīng)的配置配置文件,重啟之后,肯定直接全局實(shí)現(xiàn),所有需要用到全局加載的 xml 文件,都可以進(jìn)行實(shí)現(xiàn)了。
修改內(nèi)容如下:
局部延遲加載
在association和collection標(biāo)簽中都有?個fetchType屬性,通過修改它的值,可以修改局部的加載策略。
實(shí)現(xiàn)方式如下:
其實(shí)在這里,我們需要注意一個內(nèi)容,那就是延遲加載的時候:局部的加載策略的優(yōu)先級高于全局的加載策略。
這個也是面試的時候,經(jīng)常會被問到的內(nèi)容。
那么我們就得來看看這個延遲加載的具體實(shí)現(xiàn):
Spring配置加載
public class Configuration {
/**
* aggressiveLazyLoading:
* 當(dāng)開啟時,任何?法的調(diào)?都會加載該對象的所有屬性。否則,每個屬性會按需加載(參考lazyLoadTriggerMethods).
* 默認(rèn)為true
*/
protected boolean aggressiveLazyLoading;
/**
* 延遲加載觸發(fā)?法
*/
protected Set lazyLoadTriggerMethods = new HashSet(Arrays.asList(new String[]{"equals", "clone", "hashCode", "toString" }));
/**
* 是否開啟延遲加載
*/
protected boolean lazyLoadingEnabled = false;
/**
* 默認(rèn)使?Javassist代理??
*
* @param proxyFactory
*/
public void setProxyFactory(ProxyFactory proxyFactory) {
if (proxyFactory == null) {
proxyFactory = new JavassistProxyFactory();
}
this.proxyFactory = proxyFactory;
}
//省略...
} Spring的加載,我們已經(jīng)看到了,接下來我們還得看看延遲加載代理對象創(chuàng)建,他都是怎么來創(chuàng)建的,說到創(chuàng)建類,那么就得找到這個 ResultSetHandler 這個類了,內(nèi)部是有有個 handleResultSets 的方法,而方法內(nèi)部,就有加載的過程。默認(rèn)采用javassistProxy進(jìn)行代理對象的創(chuàng)建
// 創(chuàng)建映射后的結(jié)果對象
private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, ResultLoaderMap lazyLoader, String columnPrefix) throws SQLException {
// useConstructorMappings ,表示是否使用構(gòu)造方法創(chuàng)建該結(jié)果對象。此處將其重置
this.useConstructorMappings = false; // reset previous mapping result
final List> constructorArgTypes = new ArrayList<>(); // 記錄使用的構(gòu)造方法的參數(shù)類型的數(shù)組
final List 如果你想要在你的代碼中驗(yàn)證延遲加載是否生效的話,那么有一個很簡單的方法,開啟日志的 SQL 打印功能,那么就可以直接驗(yàn)證你的延遲加載是否生效了。
為什么需要延遲加載
其實(shí)這也是延遲加載的優(yōu)點(diǎn),優(yōu)點(diǎn)如下:
先從單表查詢,需要時再從關(guān)聯(lián)表去關(guān)聯(lián)查詢,??提?數(shù)據(jù)庫性能,因?yàn)椴樵儐伪硪汝P(guān)聯(lián)查詢多張表速度要快。
但是缺點(diǎn)也很明顯:
有當(dāng)需要用到數(shù)據(jù)時,才會進(jìn)行數(shù)據(jù)庫查詢,這樣在大批量數(shù)據(jù)查詢時,因?yàn)椴樵児ぷ饕惨臅r間,所以可能造成?戶等待時間變長,造成用戶體驗(yàn)下降。
網(wǎng)頁名稱:MyBatis的延遲加載,你知道是怎么實(shí)現(xiàn)的么?
本文鏈接:http://www.dlmjj.cn/article/ccdopie.html


咨詢
建站咨詢
