mybatis一級快取和二級快取,第二天

2021-08-14 18:08:12 字數 4068 閱讀 4701

正如大多數持久層框架一樣,mybatis 同樣提供了一級快取二級快取的支援

一級快取: 基於perpetualcache 的 hashmap本地快取,其儲存作用域為session,當session flush 或 close之後,該session中的所有 cache 就將清空

2.二級快取,如 ehcache。

3. 對於快取資料更新機制,當某乙個作用域(一級快取session/二級快取namespaces)的進行了 c/u/d 操作後,預設該作用域下所有 select 中的快取將被clear。

mybatis的一級快取:

mybatis會在表示會話的sqlsession物件中建立乙個簡單的快取,將每次查詢到的結果結果快取起來,

當下次查詢的時候,如果判斷先前有個完全一樣的查詢,會直接從快取中直接將結果取出,返回給使用者,

不需要再進行一次資料庫查詢了。

mybatis會在一次會話的表示----乙個sqlsession物件中建立乙個本地快取(local cache),

對於每一次查詢,都會嘗試根據查詢的條件去本地快取中查詢是否在快取中,如果在快取中,

就直接從快取中取出,然後返回給使用者;否則,從資料庫讀取資料,將查詢結果存入快取並返回給使用者。

一級快取是sqlsession級別的快取。在運算元據庫時需要構造 sqlsession物件,在物件中有乙個(記憶體區域)資料結構(hashmap)用於儲存快取資料。不同的sqlsession之間的快取資料區域(hashmap)是互相不影響的。

一級快取的作用域是同乙個sqlsession,在同乙個sqlsession中兩次執行相同的sql語句,第一次執行完畢會將資料庫中查詢的資料寫到快取(記憶體),第二次會從快取中獲取資料將不再從資料庫查詢,從而提高查詢效率。當乙個sqlsession結束後該sqlsession中的一級快取也就不存在了。mybatis預設開啟一級快取。

如果快取中有資料就不用從資料庫中獲取,大大提高系統效能。

namespace

=>

<

selectid=

"findusers"

resulttype

="cn.elinzhou.mybatistest.pojo.user"

>

select

* from

user

select

>

public

inte***ce

然後編寫乙個單元測試

public

class

@test

public

void

testfindusers

()throws

exception

}

執行,可以看到控制台輸出(先配好log4j)為類似如下圖日誌 

日誌說明了該操作執行的sql語句已經查詢的內容,最後一行是我手動通過system.out.printf輸出的結果。

然後再加一條語句

users =.

findusers

();

之前的單元測試就變成了這個樣子

mybatis一級快取是指在記憶體中開闢一塊區域,用來儲存使用者對資料庫的操作資訊(sql)和資料庫返回的資料,如果下一次使用者再執行相同的請求,那麼直接從記憶體中讀數資料而不是從資料庫讀取。 

其中資料的生命週期有兩個影響因素。

對sqlsession執行commit操作時

對sqlsession執行commit操作,也就意味著使用者執行了update、delete等操作,那麼資料庫中的資料勢必會發生變化,如果使用者請求資料仍然使用之前記憶體中的資料,那麼將讀到髒資料。所以在執行sqlsession操作後,會清除儲存資料的hashmap,使用者在發起查詢請求時就會重新讀取資料並放入一級快取中了。

上述測試就是在第一查詢完後執行了commit操作,再進行查詢。與之前的測試不同的是,這次測試控制台列印了兩組查詢結果,說明在commit之後mybatis對資料重新進行了查詢。

關閉sqlsession

在使用二級快取之前,先測試之前提到過的關閉sqlsession後會清空快取的問題,把junit**修改一下

說明關閉了sqlsession後的確把之前的快取資料清空了,之後再執行同樣的查詢操作也會再訪問一遍資料庫。為了解決這個問題,需要使用二級快取

接下測試,先需要開啟二級快取。

1.開啟二級快取總開關 

開啟總開關,只需要在mybatis總配置檔案中加入一行設定

<

settings

>

<

setting

name

="cacheenabled"

value

="true"

/>

settings

>

<

cache

/>

3.pojo序列化

讓需要使用二級快取的pojo類實現serializable介面,如

public

class

user

implements

serializable

執行後可以發現,控制台值輸出了一次查詢過程,也可以證明二級快取開啟成功。

還有乙個問題,之前說了,即使開啟了二級快取,不同的sqlsession之間的快取資料也不是想互訪就能互訪的,必須等到sqlsession關閉了以後,才會把其一級快取中的資料寫入二級快取。為了測試這個,把上述**中的

sqlsession

.close

();

注釋,那麼之前的**就變成了 

再執行,發現控制太又輸出了兩次的查詢過程,所以可以印證,只有關閉了sqlsession之後,才會把其中一級快取資料寫入二級快取。

在預設情況下,當sqlsession執行commit後會重新整理快取,但是也可以強制設定為不重新整理,在不需要重新整理的標籤中加入

flushcache

="false"

<

selectid=

"findusers"

resulttype

="cn.elinzhou.mybatistest.pojo.user"

flushcache

="false"

>

那麼,無論是否執行commit,快取都不會重新整理了。但是這樣會造成髒讀,只有在特殊情況下才使用

flushinterval

="10000"

該屬性表示每隔10秒鐘自動重新整理一遍快取

關閉二級快取 Mybatis一級快取 二級快取詳講

首先,我們先看一下這個標題 查詢快取 那就說明跟增 刪 改是沒有任何關聯的,只有在查詢時,才會遇到快取,增刪改不涉及!查詢快取目前mybatis中提供了兩個,分別是 一級快取 二級快取 所以,sqlsession的快取,是屬於一級快取 那,又有什麼用呢?比如,我們現在資料庫中有兩條資料,分別是張三跟...

mybatis查詢快取之一級快取和二級快取詳細解析

一級快取是mybatis預設就幫我們開啟的,我們不需要多做配置,但是我們得知道其中原理,否則我們也不知道怎麼使用,也不知道我們到底有沒有一級快取。上面第二部分說過一級快取的作用域是同乙個sqlsession,sqlsession的作用就是建立和資料庫的會話,我們對資料庫表的增刪改查都是通過sqlse...

mybatis 快取(一級和二級快取)

1.快取 好處 快取的使用演示 1 sql語句或查詢條件不同 2 分屬不同sqlsession物件 3 查詢前執行clearcache 4 提交事務 2.一級快取 3.二級快取 跟 web應用中 物件作用範圍類似。cacheenabled value true flushinterval 快取重新整...