mybatis一級快取詳解

2021-10-01 11:26:34 字數 3581 閱讀 7530

1.mybatis一級快取

一級快取: sqlsession快取 [會話快取]。預設開啟,使用者不能關閉(有方法讓其失效)。通過同乙個sqlsession呼叫同乙個查詢方法兩次,第二次查詢走的快取。

下面我們就看看一級快取怎麼儲存的?

在建立sqlsession的時候會建立executor

baseexecutor裡有個屬性localcache就是儲存一級快取內容的

public

abstract

class

baseexecutor

implements

executor

cachekey怎麼生成的?

@override

public cachekey createcachekey

cachekey cachekey =

newcachekey()

; cachekey.

update

(ms.

getid()

);//statmentid

cachekey.

update

(rowbounds.

getoffset()

);//預設是0

cachekey.

update

(rowbounds.

getlimit()

);//預設是 integer.max_value

cachekey.

update

(boundsql.

getsql()

);//sql語句()

; typehandlerregistry typehandlerregistry = ms.

getconfiguration()

.gettypehandlerregistry()

;// mimic defaultparameterhandler logic 方法的引數

forelse

if(parameterobject == null)

else

if(typehandlerregistry.

hastypehandler

(parameterobject.

getclass()

))else

cachekey.

update

(value);}

}if(configuration.

getenvironment()

!= null)

return cachekey;

}

根據statmentid,rowbounds,sql,引數生存cachekey

cachekey這個類是重寫了equals方法的

@override

public

boolean

equals

(object object)if(

!(object instanceof

cachekey))

final cachekey cachekey =

(cachekey) object;

if(hashcode != cachekey.hashcode)

if(checksum != cachekey.checksum)

if(count != cachekey.count)

for(

int i =

0; i < updatelist.

size()

; i++)}

return

true

;}

首先hashcode,checksum,count必須相等,然後分別對比什麼生存key的幾個引數(statmentid,rowbounds,sql等),這些條件都滿足時才出走快取

接下來看看快取什麼時候放進去的?

private

list

queryfromdatabase

throws sqlexception

finally

localcache.

putobject

(key, list);if

(ms.

getstatementtype()

== statementtype.callable)

return list;

}

在從資料庫查詢的時候,先是放了個佔位符execution_placeholder,然後執行查詢,再通過key刪除佔位符,最後就查詢的資料放入一級快取localcache中(我暫時也不知道為什麼要這麼設計。)

接下來看看在什麼地方從快取中取得?

@suppresswarnings

("unchecked"

)@override

public

list

query

throws sqlexception

if(querystack ==

0&& ms.

isflushcacherequired()

) list

list;

tryelse

}finally

if(querystack ==0)

// issue #601

deferredloads.

clear()

;//當設定localcachescope=statment時,一級快取就失效了,每次查詢完都會清空一級快取

if(configuration.

getlocalcachescope()

== localcachescope.statement)

}return list;

}

通過cachekey從快取中取,沒取到時才會去查資料庫

最後看看什麼時候會清空快取?

1.在進行insert,update,delete時會清空快取

看看update方法:

@override

public

intupdate

throws sqlexception

clearlocalcache()

;//清空一級快取

return

doupdate

(ms, parameter)

;}

2.在呼叫sqlsession的close()和clearcache()方法的時候,一級快取本來就是會話快取。

3.直接使一級快取失效,

"localcachescope" value=

"statment"

/>

MyBatis 快取詳解 一級快取驗證

基於mybatis standalone 工程,注意演示一級快取需要先關閉二級快取,localcachescope 設定為session 判斷是否命中快取 如果再次傳送sql 到資料庫執行,說明沒有命中快取 如果直接列印物件,說明是從記憶體快取中取到了結果。1 在同乙個session 中共享 2 不...

mybatis一級快取

autowired private sqlsessionfactory sqlsessionfactory autowired test transactional public void test selectall.size log.info 第2次查詢 selectall2.size 同乙個s...

MyBatis 一級快取

本地快取作用域預設為該sqlsession。當session flush或 close後,該session中的所有cache將清空。同一次會話期間,只要查詢過的資料都會儲存在當前sqlsession的乙個map中 key hashcode 查詢sql的id 編寫的sql語句 引數 1.不同的sqls...