Ehcache二級緩存,查詢緩存,分佈式緩存總結

二級緩存和查詢緩存都相當於一個map

二級緩存緩存的keyidvalue爲實體對象。一般load(),iterate()使用到二級緩存,list()需要結合查詢緩存使用。iterate()和list()區別如下:

iterate()不需要開啓查詢緩存,它首先發出一個sqlselect s.id from Student s去數據庫把id屬性列表取出來,然後再根據id列表一個一個load(),如果緩存有從緩存取,如果緩存沒有就從數據庫取:select s.id,s.name,s.classid from     Student s where s.id=?,取出後再存入二級緩存。Iterate總會發出取id列表的語句。

List()需要開啓查詢緩存,它首先發出一個sqlselect s.id,s.name,s.classid from Student s…”去數據庫取出所有相關實體,並將這些實體存入二級緩存,將此sql語句及一些相關信息作爲keyid列表作爲值,第二次查詢這條語句時就會去根據sql語句及相關信息去key裏找,如果有就會把id列表取出一個一個load(),接下來就和iterate一樣了。List一般只有第一次發發出取實體列表的語句,以後的id列表就會去查詢緩存取id列表,不會再發出sql語句。

 

前提:執行同一hql語句,如:select s from Student s

1.  關閉查詢緩存,開啓二級緩存時:

第二次查詢屬性時iterate只會發出獲取id列表的sqllist會發出和第一次一樣的請求實體的sql

2.  開啓查詢緩存,開啓二級緩存

第二次查詢屬性時iterate只會發出獲取id列表的sqllist不發sql

以上說明iterate只和二級緩存有關,list和二級緩存和查詢緩存都有關。

 

查詢緩存的key是一個QueryKey(其屬性如下),valueid集合。


  1. public class QueryKey implements Serializable { 
  2.    private final String sqlQueryString;//sql語句 
  3.    private final Type[] types; 
  4.    private final Object[] values; 
  5.    private final Integer firstRow;//要查詢的起始數 
  6.    private final Integer maxRows;//要查詢的個數 
  7.    private final Map namedParameters; 
  8.    private final EntityMode entityMode; 
  9.    private final Set filters; 
  10.    private final int hashCode; 
  11.    ...... 
果以上屬性中有一個不同,查詢緩存就不會命中。使用list()時,如果是第一次,查詢緩存取出實體列表,然後從實體列表中提取出id列表作爲value。如果是查詢緩存命中,就會根據QueryKey取出id列表,然後根據id列表去二級緩存中load()對象,如果二級緩存中沒有哪個對象,就會根據id去數據庫查詢,二級緩存中沒有n個對象就會去數據庫查詢n次:select p from pojo p where id=?,因此就會有機會出現傳說中n+1問題。

在查詢緩存中,查詢緩存緩存普通屬性,即對於屬性的查詢,value值爲要查詢的屬性列表,對於實體,value值爲實體的id列表,而對於屬性的查詢由於從value中直接可以查出就不會用到二級緩存,但對於實體的查詢,必須結合二級緩存使用。下面對此進行說明:

前提:執行同一hql語句,如:select s from Student sselect s.name from Student s

1.  開啓查詢緩存,關閉二級緩存時:

第二次查詢屬性時不會發出sql,第一次查詢實體時會發出sql

2.  開啓查詢緩存,開啓二級緩存

第二次查詢屬性,實體時都不發sql

 

 

對於Ehcache分佈式緩存,好像查詢緩存不能更新:

在同一系統中,當用Hibernate的方式修改表數據(save,update,delete等等),這時EhCache會自動把緩存中關於此表的所有緩存全部刪除掉(這樣能達到同步)。但對於兩個以上系統部署在不同機子上,並在他們之間配置了ehcache的分佈式緩存,當A系統修改表數據(save,update,delete)後,b系統會更新查詢緩存嗎?

答:好像是不能的,即ehcache的分佈式緩存對查詢緩存無效。(我在項目中配置了Ehcache的分佈式緩存,二級緩存可以生效,但查詢緩存不能更新。是不是一個系統中的Hibernate不能夠識別其他系統中hibernate是否進行了save,update,delete操作?而Ehcache也沒對此進行整合,望知道的大牛給說一下。)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章