<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          被面試官拷打 MyBatis 的多級(jí)緩存機(jī)制,這樣答就過了

          共 5989字,需瀏覽 12分鐘

           ·

          2024-06-17 13:58

          上周三,小 X 去面試一家中廠,其中面試官問到 MyBatis 的多級(jí)緩存機(jī)制是怎么樣運(yùn)行的?這個(gè)問題可以好好準(zhǔn)備一下,很多人可能只會(huì)用 MyBatisPlus,簡單的多表聯(lián)查 SQL 語句可能都寫不出來,更別說索引優(yōu)化、SQL 語句優(yōu)化、安全漏洞等問題了,先打好基礎(chǔ),才能更好地學(xué)習(xí)。

          題目

          MyBatis 的多級(jí)緩存機(jī)制是怎么樣運(yùn)作的?

          更多面試題目請見  

          推薦解析

          一級(jí)緩存

          1)MyBatis 的一級(jí)緩存默認(rèn)開啟,且默認(rèn)作用范圍為 SESSION,即一級(jí)緩存在一個(gè)會(huì)話中生效,也可以通過配置將作用范圍設(shè)置為 STATEMENT,讓一級(jí)緩存僅針對(duì)當(dāng)前執(zhí)行的 SQL 語句生效。2)在同一個(gè)會(huì)話中,執(zhí)行增,刪,改操作會(huì)使本會(huì)話中的一級(jí)緩存失效。3)不同會(huì)話持有不同的一級(jí)緩存,本會(huì)話內(nèi)的操作不會(huì)影響其它會(huì)話內(nèi)的一級(jí)緩存。

          Session 針對(duì)瀏覽器會(huì)話,不同會(huì)話的同一個(gè) SQL 語句,自然是不會(huì)走一級(jí)緩存。同一個(gè)瀏覽器會(huì)話,但是查詢條件不同,比如 Where 條件不同,依然不會(huì)走一級(jí)緩存,或者同一個(gè)瀏覽器在兩個(gè)相同的查詢條件下,中間執(zhí)行了一次增、刪、改的操作,一級(jí)緩存依然失效。

          特別注意:一級(jí)緩存針對(duì)的范圍是什么?以及一級(jí)緩存失效的場景,當(dāng)然一般我們都會(huì)在 yml 配置中去開啟日志,通過查看日志可以看到緩存是否被使用!

          二級(jí)緩存

          1) MyBatis 中的二級(jí)緩存默認(rèn)開啟,可以在 MyBatis 配置文件中的<settings>中添加<setting name="cacheEnabled" value="false"/>將二級(jí)緩存關(guān)閉;2)MyBatis 中的二級(jí)緩存作用范圍是同一命名空間下的多個(gè)會(huì)話共享,這里的命名空間就是映射文件的 namespace,即不同會(huì)話使用同一映射文件中的 SQL 語句對(duì)數(shù)據(jù)庫執(zhí)行操作并提交事務(wù)后,均會(huì)影響這個(gè)映射文件持有的二級(jí)緩存;3)MyBatis 中執(zhí)行查詢操作后,需要提交事務(wù)才能將查詢結(jié)果緩存到二級(jí)緩存中;4)MyBatis 中執(zhí)行增,刪或改操作并提交事務(wù)后,會(huì)清空對(duì)應(yīng)的二級(jí)緩存;5)MyBatis 中需要在映射文件中添加<cache>標(biāo)簽來為映射文件配置二級(jí)緩存,也可以在映射文件中添加<cache-ref>標(biāo)簽來引用其它映射文件的二級(jí)緩存以達(dá)到多個(gè)映射文件持有同一份二級(jí)緩存的效果。

          二級(jí)緩存配置項(xiàng)

          在 Mapper 配置文件中添加的 Cache 標(biāo)簽中可以設(shè)置相關(guān)屬性。

          1)Eviction 屬性:緩存回收策略(LRU、FIFO、SOFT、WEAK)

          2)FlushInterval屬性:刷新間隔,單位毫秒,默認(rèn)沒有刷新間隔,語句被調(diào)用時(shí)緩存會(huì)刷新。

          3)Size:引用的數(shù)目,緩存存儲(chǔ)的對(duì)象數(shù)量,考慮到內(nèi)存溢出問題。

          4)ReadOnly:只讀,是否是只讀緩存,如果為 true,所有調(diào)用者返回緩存對(duì)象的相同實(shí)例。如果為 false,會(huì)返回緩存對(duì)象的拷貝(序列化對(duì)象),性能慢,但安全性高,默認(rèn)為 false。

          是否需要三級(jí)緩存?

          概念:三級(jí)緩存通常指的是在分布式系統(tǒng)中,跨應(yīng)用實(shí)例的緩存層,如使用 Redis 或 Memcached 作為緩存存儲(chǔ)。

          作用:三級(jí)緩存可以進(jìn)一步減少對(duì)數(shù)據(jù)庫的訪問,提高系統(tǒng)的擴(kuò)展性和性能。

          考慮因素:是否需要三級(jí)緩存取決于應(yīng)用的規(guī)模、架構(gòu)和性能需求。如果應(yīng)用部署在多個(gè)服務(wù)器上,且需要共享數(shù)據(jù),可能需要考慮引入三級(jí)緩存。

          實(shí)現(xiàn):三級(jí)緩存通常不是由 MyBatis 直接提供,而是通過集成外部緩存系統(tǒng)來實(shí)現(xiàn)。

          應(yīng)用規(guī)模:對(duì)于大型應(yīng)用或分布式系統(tǒng),三級(jí)緩存可以提供更好的性能和擴(kuò)展性。

          性能需求:如果應(yīng)用對(duì)性能有較高要求,尤其是在高并發(fā)場景下,三級(jí)緩存可以顯著減少數(shù)據(jù)庫的壓力。

          數(shù)據(jù)一致性:引入三級(jí)緩存需要考慮數(shù)據(jù)一致性問題,確保緩存與數(shù)據(jù)庫之間的數(shù)據(jù)同步。

          復(fù)雜性:實(shí)現(xiàn)三級(jí)緩存可能會(huì)增加系統(tǒng)的復(fù)雜性,需要權(quán)衡實(shí)現(xiàn)成本和性能收益。

          其他補(bǔ)充

          魚聰明 AI 的回答:

          魚聰明 AI 地址:https://www.yucongming.com/

          一級(jí)緩存示例:

          一級(jí)緩存是自動(dòng)啟用的,不需要額外配置。它通常在 SqlSession 的生命周期內(nèi)有效。

          // 獲取 SqlSession
          SqlSession session = sqlSessionFactory.openSession();

          try {
              // 查詢用戶,一級(jí)緩存會(huì)自動(dòng)存儲(chǔ)這個(gè)查詢結(jié)果
              User user1 = session.selectOne("com.example.mapper.User.selectById"1L);

              // 再次查詢相同的用戶,這次將從一級(jí)緩存中獲取結(jié)果
              User user2 = session.selectOne("com.example.mapper.User.selectById"1L);

              // 檢驗(yàn)緩存是否失效:在一級(jí)緩存中,可以通過比較 user1 和 user2 是否相同來檢驗(yàn)
              if (user1 == user2) {
                  System.out.println("一級(jí)緩存有效");
              } else {
                  System.out.println("一級(jí)緩存失效");
              }

          finally {
              session.close(); // 關(guān)閉 SqlSession,結(jié)束一級(jí)緩存的生命周期
          }

          二級(jí)緩存示例:

          二級(jí)緩存需要在 MyBatis 配置文件中配置,并在 Mapper 接口上使用 @CacheNamespace 注解。

          <!-- mybatis-config.xml -->
          <configuration>
              <settings>
                  <!-- 啟用二級(jí)緩存 -->
                  <setting name="cacheEnabled" value="true"/>
              </settings>
              
              <!-- 配置二級(jí)緩存的類型,這里使用 MyBatis 內(nèi)置的 PerpetualCache -->
              <cache type="org.apache.ibatis.cache.impl.PerpetualCache">
                  <!-- 二級(jí)緩存的大小限制 -->
                  <property name="size" value="1024"/>
              </cache>
          </configuration>
          // 在 Mapper 接口上使用 @CacheNamespace 注解
          @CacheNamespace
          public interface UserMapper {
              User selectById(Long id);
          }
          // 使用二級(jí)緩存的示例
          SqlSession session = sqlSessionFactory.openSession();

          try {
              // 查詢用戶,結(jié)果將被存儲(chǔ)在二級(jí)緩存中
              User user1 = session.getMapper(UserMapper.class).selectById(1L);

              // 關(guān)閉當(dāng)前會(huì)話,然后重新打開一個(gè)新的會(huì)話
              session.close();
              session = sqlSessionFactory.openSession();

              // 在新的會(huì)話中再次查詢相同的用戶,這次將從二級(jí)緩存中獲取結(jié)果
              User user2 = session.getMapper(UserMapper.class).selectById(1L);

              // 檢驗(yàn)緩存是否失效:在二級(jí)緩存中,可以通過比較 user1 和 user2 是否相同來檢驗(yàn)
              if (user1 == user2) {
                  System.out.println("二級(jí)緩存有效");
              } else {
                  System.out.println("二級(jí)緩存失效");
              }

          finally {
              session.close(); // 關(guān)閉 SqlSession
          }

          檢驗(yàn)緩存是否失效:

          • 一級(jí)緩存:由于一級(jí)緩存僅在 SqlSession 的生命周期內(nèi)有效,通常不需要手動(dòng)檢驗(yàn)緩存是否失效。當(dāng) SqlSession 關(guān)閉時(shí),一級(jí)緩存自動(dòng)失效。
          • 二級(jí)緩存:可以通過比較兩次查詢返回的對(duì)象引用是否相同來檢驗(yàn)緩存是否失效。如果相同,說明緩存有效;如果不同,說明緩存可能已經(jīng)失效。

          歡迎交流

          本文主要介紹 MyBatis 的一二級(jí)緩存和緩存失效的主要場景,以及是否需要三級(jí)緩存的問題,關(guān)于數(shù)據(jù)庫方面是一個(gè)重點(diǎn)項(xiàng),因?yàn)椴煌Z言都需要利用數(shù)據(jù)庫進(jìn)行持久化存儲(chǔ),無論哪種 ORM 框架都有各自的優(yōu)缺點(diǎn),需要根據(jù)實(shí)際場景進(jìn)行選擇,在文末還有三個(gè)提問,歡迎小伙伴在評(píng)論區(qū)進(jìn)行留言!近期面試鴨小程序已全面上線,想要刷題的小伙伴可以積極參與!

          1)一級(jí)緩存和二級(jí)緩存的區(qū)別是什么?

          2)如何配置和管理二級(jí)緩存?

          3)MyBatis的一級(jí)緩存是如何工作的?它的生命周期是什么時(shí)候開始和結(jié)束的?什么情況下會(huì)導(dǎo)致一級(jí)緩存的失效或刷新?


          點(diǎn)燃求職熱情!每周持續(xù)更新,海量面試題和大廠面經(jīng)等你挑戰(zhàn)!趕緊關(guān)注面試鴨公眾號(hào),輕松備戰(zhàn)秋招和暑期實(shí)習(xí)!


          往期推薦

          小黑子!微服務(wù)鏈路追蹤都不知道?

          關(guān)于 Bean 容器的注入方式,99 % 的人都答不全!

          SpringBoot 同時(shí)可以處理多少請求?這可難倒了不少人

          慢 SQL 監(jiān)控都不會(huì)?Out!

          面試官:Spring Bean 的生命周期都不會(huì),你走吧下一位

          面試官說要壓測我的網(wǎng)站,我被壓力了!


          瀏覽 162
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  伊人久久大香线蕉久久婷婷 | 欧洲亚洲无码视频 | 人人妻人人摸 | 国产精品婷婷 | 操进你的小穴里在线观看 |