當前位置:首頁 » 硬碟大全 » mybatis如何讓對象進入一級緩存
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

mybatis如何讓對象進入一級緩存

發布時間: 2023-01-13 15:00:55

『壹』 mybatis的一級緩存

你好,你的想法是對的,應為以及緩存是依賴於sqlsession的,如果關閉session緩存將會消失。其實所謂的緩存就是map,他是以map集合來存儲數據的,而這個map就在session中的一個緩存方法當中。

『貳』 pve開啟一級緩存

pve開啟一級緩存的方法如下:
1、配置在一級緩存中緩存對象的個數,Mybatis的一級緩存SqlSession默認是開啟的。
2、自己去開啟二級緩存在config.xml文件中的properties下面可加上這個配置。

『叄』 mybatis的緩存機制是怎麼樣的

你好,正如大多數持久層框架一樣,MyBatis 同樣提供了一級緩存和二級緩存的支持。
1.緩存,其存儲作用域為 Session,當 Session flush 或 close 之後,該Session中的所有 Cache 就將清空。
2. 二級緩存與一級緩存其機制相同,默認也是採用 PerpetualCache,HashMap存儲,不同在於其存儲作用域為 Mapper(Namespace),並且可自定義存儲源,如 Ehcache。
3. 對於緩存數據更新機制,當某一個作用域(一級緩存Session/二級緩存Namespaces)的進行了 C/U/D 操作後,默認該作用域下所有 select 中的緩存將被clear。

mybatis的一級緩存作用就是在同一個session過程中,將會對相同數據的存取不通過資料庫,而是通過緩存機制提高效率。
希望對你有幫助~

『肆』 Mybatis的緩存講解

前段時間阿粉的一個朋友和阿粉吃飯,在吃飯的時候和阿粉瘋狂的吐槽面試官,說面試官問的問題都是些什麼問題呀,我一個幹了三四年的開發,也不說問點靠譜的,阿粉很好奇,問題問完基礎的,一般不都是根據你自己的簡歷進行提問么?而接下來他說的出來的問題,阿粉表示,阿粉需要繼續學習了。

說到這個,讀者大人們肯定心想,阿粉是在開玩笑么?你一個 Java 程序員,你不知道Mybatis是啥么?不就是個持久層的框架么,這東西有啥好說的呢?但是阿粉還是要給大家說。

為什麼說 Mybatis 是一個半自動 ORM 的框架呢?

ORM,是Object和Relation之間的映射,而Mybatis 在查詢關聯對象或關聯集合對象時,需要手動編寫 sql 來完成,所以,稱之為半自動 ORM 框架,而Hibernate 屬於全自動 ORM 映射工具,使用 Hibernate 查詢關聯對象或者關聯集合對象時,可以根據對象關系模型直接獲取,所以它是全自動的。

這也是為什麼有些面試官在面試初級程序員的時候,很喜歡說,你覺得 Mybatis , 和 Hibernate 都有什麼優缺點,為啥你們選擇使用的 Mybatis 而不選擇使用 Hibernate 呢?

我們都說了 Mybatis是什麼了,接下來肯定需要說說面試官都問了什麼問題,能讓阿粉的朋友變得非常猶豫。

當我們面試的時候,說完這個,一般情況下,面試官一定會追問下去,畢竟技術就是要問到你的知識盲區才會停止。

那我們就來畫個圖表示一下一級緩存

那面試官肯定會說,直接從資料庫查不就行了,為啥要一級緩存呢?

當我們使用MyBatis開啟一次和資料庫的會話時, MyBatis 會創建出一個 SqlSession 對象表示一次與資料庫之間的信息傳遞,在我們執行 SQL 語句的過程中,們可能會反復執行完全相同的查詢語句,如果不採取一些措施,我們每一次查詢都會查詢一次資料庫,而如果在極短的時間內做了很多次相同的查詢操作,那麼這些查詢返回的結果很可能相同。

也就是說,如果我們在短時間內,頻繁的去執行一條 SQL ,查詢返回的結果本來應該是改變了,但是我們查詢出來的時候,會出現結果一致的情況,正是為了解決這種問題,也為了減輕資料庫的開銷,所以 Mybatis 默認開啟了一級緩存。

Mybatis 的二級緩存一般如果你不對他進行設置,他是不會開啟的,而二級緩存是什麼呢?Mybatis 中的二級緩存實際上就是 mapper 級別的緩存,而這時候肯定會有人說,那麼不同之間的 Mapper 是同一個緩存么?

答案是否定的,他不是一個,Mapper 級別的緩存實際上就是相同的 Mapper 使用的是一個二級緩存,但是在二級緩存中,又有多個不同的 SqlSession ,而不同的 Mapper 之間的二級緩存也就是互相不會影響的。

就類似下面的圖

這二級緩存是不是就看起來有點意思了?

那怎麼能夠開啟二級緩存呢?

1.MyBatis 配置文件

2.MyBatis 要求返回的 POJO 必須是可序列化的

3.Mapper 的 xml 配置文件中加入 標簽

既然我們想要了解這個二級緩存,那麼必然,我們還得知道它裡面的配置都有哪些含義。

我們先從標簽看起,然後從源碼裡面看都有哪些配置信息提供給我們使用:

blocking : 直譯就是調度,而在 Mybatis 中,如果緩存中找不到對應的 key ,是否會一直 blocking ,直到有對應的數據進入緩存。

eviction : 緩存回收策略

而緩存回收策略,在源碼中是有直接體現的,那麼他們分別都對應了什麼形式呢?

大家雖然看著 PERPETUAL 排在了第一位,但是它可不是默認的,在 Mybatis 的緩存策略裡面,默認的是 LRU 。

PERPETUAL :

源代碼如下:

恩?看著是不是有點眼熟,它怎麼就只是包裝了 HashMap ? 你還別奇怪,他還真的就是使用的 HashMap ,不得不說,雖然人家是使用的 HashMap ,但是那可是比咱們寫的高端多了。

既然使用 HashMap ,那麼必然就會有Key,那麼他們的Key是怎麼設計的?

CacheKey:

確實牛逼,至於內部如何初始化,如何進行操作,大家有興趣的可以去閱讀一下源碼,導入個源碼包,打開自己看一下。

FIFO : 先進先出緩沖淘汰策略

在 FIFO 淘汰策略中使用了 Java 中的 Deque,而 Deque 一種常用的數據結構,可以將隊列看做是一種特殊的線性表,該結構遵循的先進先出原則。Java中,LinkedList實現了Queue介面,因為LinkedList進行插入、刪除操作效率較高。

當你看完這個源碼的時候,是不是就感覺源碼其實也沒有那麼難看懂,裡面都是我們已經掌握好的知識,只不過中間做了一些操作,進行了一些封裝。

LRU : 最近最少使用的緩存策略

而 LUR 演算法,阿粉之前都說過,如果對這個演算法感興趣的話,文章地址給大家送上,經典的 LRU 演算法,你真的了解嗎?

而我們需要看的源碼則是在 Mybatis 中的源碼,

SOFT : 基於垃圾回收器狀態和軟引用規則的對象

在看到基於垃圾回收器的時候,阿粉就已經開始興奮了,竟然有GC的事情,那還不趕緊看看,這如此高大上(裝杯)的事情,來瞅瞅吧!

WEAK : 基於垃圾收集器狀態和弱引用規則的對象

WeakCache在實現上與SoftCache幾乎相同,只是把引用對象由SoftReference軟引用換成了WeakReference弱引用。

在這里阿粉也就不再多說了,關於 Mybatis 的二級緩存,你了解了么?下次遇到面試官問這個的時候,你應該知道怎麼成功(裝杯)不被打了吧。

『伍』 mybatis怎麼實現局部緩存

1.1、Mybatis一級緩存測試

1 package me.gacl.test;
2
3 import me.gacl.domain.User;
4 import me.gacl.util.MyBatisUtil;
5 import org.apache.ibatis.session.SqlSession;
6 import org.junit.Test;
7
8 /**
9 * @author gacl
10 * 測試一級緩存
11 */
12 public class TestOneLevelCache {
13
14 /*
15 * 一級緩存: 也就Session級的緩存(默認開啟)
16 */
17 @Test
18 public void testCache1() {
19 SqlSession session = MyBatisUtil.getSqlSession();
20 String statement = "me.gacl.mapping.userMapper.getUser";
21 User user = session.selectOne(statement, 1);
22 System.out.println(user);
23
24 /*
25 * 一級緩存默認就會被使用
26 */
27 user = session.selectOne(statement, 1);
28 System.out.println(user);
29 session.close();
30 /*
31 1. 必須是同一個Session,如果session對象已經close()過了就不可能用了
32 */
33 session = MyBatisUtil.getSqlSession();
34 user = session.selectOne(statement, 1);
35 System.out.println(user);
36
37 /*
38 2. 查詢條件是一樣的
39 */
40 user = session.selectOne(statement, 2);
41 System.out.println(user);
42
43 /*
44 3. 沒有執行過session.clearCache()清理緩存
45 */
46 //session.clearCache();
47 user = session.selectOne(statement, 2);
48 System.out.println(user);
49
50 /*
51 4. 沒有執行過增刪改的操作(這些操作都會清理緩存)
52 */
53 session.update("me.gacl.mapping.userMapper.updateUser",
54 new User(2, "user", 23));
55 user = session.selectOne(statement, 2);
56 System.out.println(user);
57
58 }
59 }

1.2、Mybatis二級緩存測試
1、開啟二級緩存,在userMapper.xml文件中添加如下配置
<mapper namespace="me.gacl.mapping.userMapper">
<!-- 開啟二級緩存 -->
<cache/>

2、測試二級緩存

1 package me.gacl.test;
2
3 import me.gacl.domain.User;
4 import me.gacl.util.MyBatisUtil;
5 import org.apache.ibatis.session.SqlSession;
6 import org.apache.ibatis.session.SqlSessionFactory;
7 import org.junit.Test;
8
9 /**
10 * @author gacl
11 * 測試二級緩存
12 */
13 public class TestTwoLevelCache {
14
15 /*
16 * 測試二級緩存
17 * 使用兩個不同的SqlSession對象去執行相同查詢條件的查詢,第二次查詢時不會再發送SQL語句,而是直接從緩存中取出數據
18 */
19 @Test
20 public void testCache2() {
21 String statement = "me.gacl.mapping.userMapper.getUser";
22 SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
23 //開啟兩個不同的SqlSession
24 SqlSession session1 = factory.openSession();
25 SqlSession session2 = factory.openSession();
26 //使用二級緩存時,User類必須實現一個Serializable介面===> User implements Serializable
27 User user = session1.selectOne(statement, 1);
28 session1.commit();//不懂為啥,這個地方一定要提交事務之後二級緩存才會起作用
29 System.out.println("user="+user);
30
31 //由於使用的是兩個不同的SqlSession對象,所以即使查詢條件相同,一級緩存也不會開啟使用
32 user = session2.selectOne(statement, 1);
33 //session2.commit();
34 System.out.println("user2="+user);
35 }
36 }

1.3、二級緩存補充說明
1. 映射語句文件中的所有select語句將會被緩存。
2. 映射語句文件中的所有insert,update和delete語句會刷新緩存。
3. 緩存會使用Least Recently Used(LRU,最近最少使用的)演算法來收回。
4. 緩存會根據指定的時間間隔來刷新。
5. 緩存會存儲1024個對象
cache標簽常用屬性:
<cache
eviction="FIFO" <!--回收策略為先進先出-->
flushInterval="60000" <!--自動刷新時間60s-->
size="512" <!--最多緩存512個引用對象-->
readOnly="true"/> <!--只讀-->

『陸』 mybatis的緩存機制是怎麼樣的

MyBatis將數據緩存設計成兩級結構,分為一級緩存、二級緩存:
一級緩存是Session會話級別的緩存,位於表示一次資料庫會話的SqlSession對象之中,又被稱之為本地緩存。一級緩存是MyBatis內部實現的一個特性,用戶不能配置,默認情況下自動支持的緩存,用戶沒有定製它的權利(不過這也不是絕對的,可以通過開發插件對它進行修改);
二級緩存是Application應用級別的緩存,它的是生命周期很長,跟Application的聲明周期一樣,也就是說它的作用范圍是整個Application應用。

『柒』 mybatis一級緩存內存佔用過大的問題

內存佔用過大可以通過flushCache="true"或者where <隨機數>=<隨機數>去除MyBatis的一級緩存來解決。

1、一級緩存是SqlSession級別的緩存 —— 它是各自獨立的。

在操作資料庫時需要構造sqlSession對象,在對象中有一個數據結構(HashMap)用於存儲緩存數據。

不同的sqlSession之間的緩存數據區域(HashMap)是互相不影響的。

2、二級緩存是mapper級別的緩存 —— 它是多個 SqlSession 共享的。

多個SqlSession去操作同一個Mapper的sql語句,多個SqlSession可以共用二級緩存,二級緩存是跨SqlSession的。

『捌』 mybatis的緩存機制是怎麼樣的

通常為了減輕資料庫的壓力,我們會引入緩存。在Dao查詢資料庫之前,先去緩存中找是否有要找的數據,如果有則用緩存中的數據即可,就不用查詢資料庫了。如果沒有才去資料庫中查找。這樣就能分擔一下資料庫的壓力。另外,為了讓緩存中的數據與資料庫同步,我們應該在該數據發生變化的地方加入更新緩存的邏輯代碼。這樣無形之中增加了工作量,同時也是一種對原有代碼的入侵。這對於有著代碼潔癖的程序員來說,無疑是一種傷害。MyBatis框架早就考慮到了這些問題,因此MyBatis提供了自定義的二級緩存概念,方便引入我們自己的緩存機制,而不用更改原有的業務邏輯。

『玖』 mybatis的緩存機制是怎麼樣的

MyBatis數據緩存設計兩級結構級緩存、二級緩存:
級緩存Session級別緩存位於表示資料庫SqlSession象稱本緩存級緩存MyBatis內部實現特性用戶能配置默認情況自支持緩存用戶沒定製權利(絕通發插件進行修改);
二級緩存Application應用級別緩存命周期跟Application聲明周期說作用范圍整Application應用

『拾』 mybatis的緩存有幾種

1、一級緩存

MyBatis默認開啟了一級緩存,一級緩存是在SqlSession 層面進行緩存的。即,同一個SqlSession ,多次調用同一個Mapper和同一個方法的同一個參數,只會進行一次資料庫查詢,然後把數據緩存到緩沖中,以後直接先從緩存中取出數據,不會直接去查資料庫。

但是不同的SqlSession對象,因為不用的SqlSession都是相互隔離的,所以相同的Mapper、參數和方法,他還是會再次發送到SQL到資料庫去執行,返回結果。

2、二級緩存

為了克服這個問題,需要開啟二級緩存,是的緩存zaiSqlSessionFactory層面給各個SqlSession 對象共享。默認二級緩存是不開啟的,需要手動進行配置。

<cache/>

如果這樣配置的話,很多其他的配置就會被默認進行,如:

  • 映射文件所有的select 語句會被緩存

  • 映射文件的所有的insert、update和delete語句會刷新緩存

  • 緩存會使用默認的Least Recently Used(LRU,最近最少使用原則)的演算法來回收緩存空間

  • 根據時間表,比如No Flush Interval,(CNFI,沒有刷新間隔),緩存不會以任何時間順序來刷新

  • 緩存會存儲列表集合或對象(無論查詢方法返回什麼)的1024個引用

  • 緩存會被視為是read/write(可讀/可寫)的緩存,意味著對象檢索不是共享的,而且可以很安全的被調用者修改,不幹擾其他調用者或縣城所作的潛在修改

  • 可以在開啟二級緩存時候,手動配置一些屬性

  • <cache eviction="LRU" flushInterval="100000" size="1024" readOnly="true"/>

  • 各個屬性意義如下:

  • eviction:緩存回收策略
    - LRU:最少使用原則,移除最長時間不使用的對象
    - FIFO:先進先出原則,按照對象進入緩存順序進行回收
    - SOFT:軟引用,移除基於垃圾回收器狀態和軟引用規則的對象
    - WEAK:弱引用,更積極的移除移除基於垃圾回收器狀態和弱引用規則的對象

  • flushInterval:刷新時間間隔,單位為毫秒,這里配置的100毫秒。如果不配置,那麼只有在進行資料庫修改操作才會被動刷新緩存區

  • size:引用額數目,代表緩存最多可以存儲的對象個數

  • readOnly:是否只讀,如果為true,則所有相同的sql語句返回的是同一個對象(有助於提高性能,但並發操作同一條數據時,可能不安全),如果設置為false,則相同的sql,後面訪問的是cache的clone副本。

  • 可以在Mapper的具體方法下設置對二級緩存的訪問意願:

  • useCache配置

    如果一條語句每次都需要最新的數據,就意味著每次都需要從資料庫中查詢數據,可以把這個屬性設置為false,如:

  • <select id="selectAll" resultMap="BaseResultMap" useCache="false">

  • 刷新緩存(就是清空緩存)

    二級緩存默認會在insert、update、delete操作後刷新緩存,可以手動配置不更新緩存,如下:

  • <update id="updateById" parameterType="User" flushCache="false" />


  • 3、自定義緩存

    自定義緩存對象,該對象必須實現 org.apache.ibatis.cache.Cache 介面

每次查詢資料庫前,MyBatis都會先在緩存中查找是否有該緩存對象。只有當調用了commit() 方法,MyBatis才會往緩存中寫入數據,數據記錄的鍵為數字編號+Mapper名+方法名+SQL語句+參數格式,值為返回的對象值。