6蝙砌、延遲加載(mybatis筆記)

一、什么是延遲加載

  • 延遲加載:先從單表查詢恬总、需要時再從關(guān)聯(lián)表去關(guān)聯(lián)查詢肚邢,大大提高數(shù)據(jù)庫性能。
  • resultMap可以實現(xiàn)高級映射(使用association贱纠、collection實現(xiàn)一對一和一對多映射)谆焊,association浦夷、collection具備延遲加載的功能辜王。
  • 如果現(xiàn)在的需求:
    查詢訂單并且關(guān)聯(lián)查詢用戶信息剃执。如果先查詢訂單信息即可滿足要求肾档,當(dāng)我們需要用戶信息時再查詢用戶信息。把對用戶信息的按需查詢就是延遲加載俗慈。

二遣耍、使用association實現(xiàn)延遲加載

需求在上面已經(jīng)給出舵变。(工程mybatis12

2.1 mapper.xml

  • 1.先只查詢訂單信息
SELECT * FROM orders

在查詢訂單的statement中使用association去延遲加載(執(zhí)行)下面的statement

  • 2.關(guān)聯(lián)查詢用戶信息
    通過上面查詢到的訂單信息中的user_id去關(guān)聯(lián)查詢用戶信息
SELECT orders.*, 
        (SELECT username FROM USER WHERE orders.`user_id` = user.`id`) username
        (SELECT sex FROM USER WHERE orders.`user_id` = user.`id`)sex 
...
FROM orders

說明:上面的sql只是說明赊豌,語法是不正確的碘饼。也就是說我們可以通過訂單信息中的user_id去關(guān)聯(lián)查詢用戶的各項信息悲伶。

OrdersMapper.xml

<!-- 延遲加載的resultMap -->
<resultMap type="Orders" id="OrdersUserLazyResultMap">
    <!-- 首先需要對訂單信息進(jìn)行配置 -->
    <id column="id" property="id"/>
    <result column="user_id" property="userId"/>
    <result column="number" property="number"/>
    <result column="createtime" property="createtime"/>
    <result column="note" property="note"/>
    
    <!-- 對用戶信息進(jìn)行延遲加載
    select:指定延遲加載要執(zhí)行的sql語句(statement)麸锉,這里根據(jù)user_id查詢用戶信息的statement,
    要使用UserMapper.xml中的findUserById來完成根據(jù)用戶id(user_id)的用戶信息查詢五慈,需要使用命名空間
    column: 訂單信息中關(guān)聯(lián)用戶信息查詢的列主穗,是user_id
    關(guān)聯(lián)查詢的sql理解為
    SELECT orders.*, 
        (SELECT username FROM USER WHERE orders.`user_id` = user.`id`) username
        (SELECT sex FROM USER WHERE orders.`user_id` = user.`id`)sex 
    FROM orders-->
    <association property="user" javaType="User" select="cn.itcast.mapper.UserMapper.findUserById" column="user_id">
    </association>
    
</resultMap>

<!-- 查詢訂單忽媒,關(guān)聯(lián)查詢用戶腋粥,用戶信息需要延遲加載 -->
<select id="findOrdersUserLazy" resultMap="OrdersUserLazyResultMap">
    SELECT * FROM orders
</select>

說明:從上面的注釋中我們可以明確的知道首先我們是查詢訂單信息(單表),在resultMap中我們使用association的延遲加載功能延遲加載用戶信息闹瞧,而用戶信息的查詢我們可以使用之前配置過的查詢statement奥邮。
注意:在配置延遲加載的時候我們使用了之前的查詢select="cn.itcast.mapper.UserMapper.findUserById",由于不再同一個mapper.xml中脚粟,所以要加上命名空間:
UserMapper.xml

<!-- 查詢蘸朋,通過用戶id進(jìn)行查詢-->
<select id="findUserById" parameterType="java.lang.Integer" resultType="User">
    SELECT * FROM USER WHERE id = #{value}
</select>

2.2 配置延遲加載功能

延遲加載配置藕坯,默認(rèn)是沒有開啟延遲加載的,需要在全局配置文件SqlMapConfig.xmlsettings中進(jìn)行配置吐根。

設(shè)置項 描述 允許值 默認(rèn)值
lazyLoadingEnabled 全局性設(shè)置懶加載佑惠。如果設(shè)置為"false"齐疙,則所有相關(guān)聯(lián)的都會被初始化加載 true/false false
aggressiveLazyLoading 當(dāng)設(shè)置為"true"的時候,懶加載的對象可能被任何懶屬性全部加載赌厅。否咋轿塔,每個屬性都按需加載勾缭。 true/false true

配置:

<settings>
    <!-- 打開延遲加載的開關(guān),再將積極加載改為消極加載(即按需加載) -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

2.3 mapper.java

OrdersMapper.java

//查詢訂單毒嫡,關(guān)聯(lián)查詢用戶兜畸,其中用戶信息是延遲加載
public List<Orders> findOrdersUserLazy() throws Exception;

2.4 測試

OrdersMapperTest.java

//查詢訂單關(guān)聯(lián)查詢用戶信息,其中用戶信息使用延遲加載
@Test
public void testFindOrdersUserLazy() throws Exception {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //創(chuàng)建代理對象
    OrdersMapper orders = sqlSession.getMapper(OrdersMapper.class);
    //查詢訂單信息(單表)
    List<Orders> list = orders.findOrdersUserLazy();
    
    //遍歷上面的訂單列表
    for(Orders order : list){
        User user = order.getUser();//這里實現(xiàn)按需加載
        System.out.println(user);
    }
    System.out.println(list.size());
    sqlSession.close();
}

說明:

  • 1.執(zhí)行上面的mapper接口中的方法伐蒂,內(nèi)部調(diào)用findOrdersUserLazy逸邦,只查詢orders信息(單表)
  • 2.在程序中去遍歷List<Orders>龄坪,當(dāng)我們調(diào)用Orders中的getUser方法時,就開始進(jìn)行延遲加載烛卧。
  • 3.延遲加載去調(diào)用findUserById這個方法獲取用戶信息总放。
  • 測試結(jié)果為:
    1

    可以看到當(dāng)用戶id一樣時局雄,是不會重復(fù)發(fā)送sql語句的存炮,這就是后面要將的緩存的概念。

2.5 如果我們不使用mybatis提供的延遲加載宫盔,我們?nèi)绾螌崿F(xiàn)延遲加載享完?

  • 實現(xiàn)方法如下:
    定義兩個mapper方法
      1. 查詢訂單列表
      1. 根據(jù)用戶id查詢用戶信息
  • 實現(xiàn)思路:
    先查詢第一個mapper的方法得到訂單信息列表般又,在程序中(service類中),按需去調(diào)用第二個mapper方法去查詢用戶信息寄悯。當(dāng)然這也是mybatis實現(xiàn)延遲加載的原理堕义。

總結(jié):使用延遲加載方法,先去查詢簡單的sql(最好是單表,也可以是關(guān)聯(lián)查詢)糖耸,然后再去按需加載關(guān)聯(lián)查詢的其他信息嘉竟。最后對于collection實現(xiàn)延遲加載的方式和上面是一樣的,這里不再細(xì)說舍扰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末边苹,一起剝皮案震驚了整個濱河市个束,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沪悲,老刑警劉巖阱表,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件最爬,死亡現(xiàn)場離奇詭異烂叔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蒜鸡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進(jìn)店門胯努,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人逢防,你說我怎么就攤上這事叶沛。” “怎么了忘朝?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵灰署,是天一觀的道長。 經(jīng)常有香客問我,道長溉箕,這世上最難降的妖魔是什么晦墙? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任肴茄,我火速辦了婚禮晌畅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寡痰。我一直安慰自己抗楔,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布拦坠。 她就那樣靜靜地躺著连躏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贞滨。 梳的紋絲不亂的頭發(fā)上入热,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天,我揣著相機(jī)與錄音疲迂,去河邊找鬼才顿。 笑死,一個胖子當(dāng)著我的面吹牛尤蒿,可吹牛的內(nèi)容都是我干的郑气。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼腰池,長吁一口氣:“原來是場噩夢啊……” “哼尾组!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起示弓,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤讳侨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后奏属,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跨跨,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年囱皿,在試婚紗的時候發(fā)現(xiàn)自己被綠了勇婴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡嘱腥,死狀恐怖耕渴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情齿兔,我是刑警寧澤橱脸,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布础米,位于F島的核電站,受9級特大地震影響添诉,放射性物質(zhì)發(fā)生泄漏屁桑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一吻商、第九天 我趴在偏房一處隱蔽的房頂上張望掏颊。 院中可真熱鬧,春花似錦艾帐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至事扭,卻和暖如春捎稚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背求橄。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工今野, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人罐农。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓条霜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親涵亏。 傳聞我的和親對象是個殘疾皇子宰睡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,654評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 主要內(nèi)容: 開發(fā)中數(shù)據(jù)模型的分析流程 一對一查詢 一對多查詢 一拆内、開發(fā)中數(shù)據(jù)模型的分析流程 一般在開發(fā)中我們會直接...
    yjaal閱讀 2,175評論 5 8
  • 非本人總結(jié)的筆記,抄點筆記復(fù)習(xí)復(fù)習(xí)宠默。感謝傳智博客及黑馬程序猿成長 關(guān)聯(lián)查詢 數(shù)據(jù)中的表結(jié)構(gòu) 數(shù)據(jù)庫的分析方法 第一...
    鍵盤瞎閱讀 1,093評論 3 5
  • 什么是延遲加載 舉個例子:如果查詢訂單并且關(guān)聯(lián)查詢用戶信息麸恍。如果先查詢訂單信息即可滿足要求,當(dāng)我們需要查詢用戶信息...
    我相信你愛過gg閱讀 230評論 0 0
  • 轉(zhuǎn)載搀矫,覺得這篇寫 SQLAlchemy Core抹沪,寫得非常不錯。不過后續(xù)他沒寫SQLAlchemy ORM... ...
    非夢nj閱讀 5,404評論 1 14
  • 您知道什么樣的作息時間才是符合自然規(guī)律的嗎艾君?冬季最佳的作息時間表又是怎樣的呢采够?現(xiàn)在就來了解吧! 在冬季冰垄,我們應(yīng)該早...
    周莫創(chuàng)客閱讀 286評論 0 1