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...