閱讀788 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Hibernate和Jive緩存策略的比較

Hibernate和Jive緩存策略的比較

 

一.基本概念

PO是持久化對象,他隻是對物理數據實體的一種對象表示。

VO是值對象,準確地講,他是業務對象。

FormBean隻是HTML表單的封裝,起到在控製層弱化的request中存儲數據的作用,將request的get方法轉

變為對象的存取值。

 

 

二.緩存策略比較

Jive

1.Jive的緩存策略的過程描述:

(1)條件查詢的時候,Jive用 select id from table_name where …. (隻選擇ID字段)這樣的SQL語句查詢數據庫,來獲得一個ID列表。

 

(2) Jive根據ID列表中的每個ID,首先查看緩存中是否存在對應ID的數據對象:假如存在,那麼直接取出,加入到 結果列表中;假如不存在,那麼通過一條select * from table_name where id = {ID value} 這樣的SQL查詢數據庫,取出對應的數據對象,放入到結果列表,並把這個數據對象按照ID放入到緩存中。

 

(3) ID查詢的時候,Jive執行類似第(2)步的過程,先從緩存中查找該ID,查不到,再查詢數據庫,然後把結果放入到緩存。

 

(4) 刪除、更新、增加數據的時候,同時更新緩存。

 

2.Jive緩存策略的長處:

(1) ID查詢的時候,假如該ID已存在於緩存中,那麼能夠直接取出。節省了一條數據庫查詢。

 

(2) 當多次條件查詢的結果集相交的情況下,交集裏麵的數據對象不用重複從數據庫整個獲取,直接從緩存中獲取即可。比如,第一次查詢的ID列表為{1, 2},然後根據ID列表的ID從數據庫中一個一個取出數據對象,結果集為{a(id = 1), b(id = 2)}。下一次查詢的ID列表為{2, 3},由於ID = 2的數據對象已存在於緩存中,那麼隻要從數據庫中取出ID = 3的數據對象即可。

 

3.Jive緩存策略的缺點:

(1) 在根據條件查找數據對象列表的過程中,DAO的第(1)步用來獲得ID列表的那一次數據庫查詢,是必不可少的。

 

(2) 假如第(1)步返回的ID列表中有n個ID,在最壞的命中率(緩存中一個對應ID都沒有)情況下,Jive還要再查詢n次數據庫。最壞情況下,共需要n + 1數據庫查詢。

Hibernate

Hibernate用Session類包裝了數據庫連接從打開到關閉的過程。Session內部維護一個數據對象集合,包括了本Session內選取的、操作的數據對象。這稱為Session內部緩存,是Hibernate的第一級最快緩存,屬於Hibernate的既定行為,無需進行配置。

Session的生命期很短,存在於Session內部的第一級最快緩存的生命期當然也很短,命中率自然也很低。當然,這個Session內部緩存的主要作用是保持Session內部數據狀態同步。假如需要跨Session的命中率較高的全局緩存,那麼必須對Hibernate進行二級緩存配置。一般來說,同樣數據類型(Class)的數據對象,共用一個二級緩存(或其中的同一塊)。

 

1.Hibernate二級緩存策略的過程描述:

(1)條件查詢的時候,總是發出一條select * from table_name where …. (選擇任何字段)這樣的SQL語句查詢數據庫,一次獲得任何的數據對象。

 

(2) 把獲得的任何數據對象根據ID放入到第二級緩存中。

 

(3) 當Hibernate根據ID訪問數據對象的時候,首先從Session一級緩存中查;查不到,假如配置了二級緩存,那麼從二級緩存中查;查不到,再查詢數據庫,把結果按照ID放入到緩存。

 

(4) 刪除、更新、增加數據的時候,同時更新緩存。

 

2.Hibernate二級緩存策略的長處:

(1) 具備Jive緩存策略同樣的第(1)條長處:ID查詢的時候,假如該ID已存在於緩存中,那麼能夠直接取出。節省了一條數據庫查詢。

 

(2) 不具備Jive緩存策略的第(2)條缺點,即hibernate不會有最壞情況下的 n + 1次數據庫查詢。

 

3.Hibernate二級緩存策略的缺點:

(1) 同Jive緩存策略的第(1)條缺點相同,條件查詢的時候,第(1)步的數據庫查詢語句是不可少的。而且Hibernate選擇任何的字段,比隻選擇ID字段花費的時間和空間都多。

 

(2) 不具備Jive緩存策略的第(2)條長處。條件查詢的時候,必須把數據庫對象從數據庫中整個取出,即使該數據庫的ID已存在於緩存中。

 

Hibernate的Query緩存策略

能夠看到,Jive緩存和Hibernate的二級緩存策略,都隻是針對於ID查詢的緩存策略,對於條件查詢則毫無作用。(盡管Jive緩存的第(2)個長處,能夠避免重複從數據庫獲取同一個ID對應的數據對象,但select id from …這條數據庫查詢是每次條件查詢都必不可少的)。

 

為此,Hibernate提供了針對條件查詢的Query緩存。

 

1.Hibernate的Query緩存策略的過程描述:

(1) 條件查詢的請求一般都包括如下信息:SQL, SQL需要的參數,記錄範圍(起始位置rowStart,最大記錄個數maxRows),等。

 

(2) Hibernate首先根據這些信息組成一個Query Key,根據這個Query Key到Query緩存中查找對應的結果列表。假如存在,那麼返回這個結果列表;假如不存在,查詢數據庫,獲取結果列表,把整個結果列表根據Query Key放入到Query緩存中。

 

(3) Query Key中的SQL涉及到一些表名,假如這些表的任何數據發生修改、刪除、增加等操作,這些相關的Query Key都要從緩存中清空。

 

2.Hibernate的Query緩存策略的長處

(1) 條件查詢的時候,假如Query Key已存在於緩存,那麼無需再查詢數據庫。命中的情況下,一次數據庫查詢也無需。

 

3.Hibernate的Query緩存策略的缺點

(1) 條件查詢涉及到的表中,假如有任何一條記錄增加、刪除、或改變,那麼緩存中任何和該表相關的Query Key都會失效。

比如,有這樣幾組Query Key,他們的SQL裏麵都包括table1。

 

SQL = select * from table1 where c1 = ? …., parameter = 1, rowStart = 11, maxRows = 20.

SQL = select * from table1 where c1 = ? …., parameter = 1, rowStart = 21, maxRows = 20.

SQL = select * from table1 where c1 = ? ….., parameter = 2, rowStart = 11, maxRows = 20.

SQL = select * from table1 where c1 = ? ….., parameter = 2, rowStart = 11, maxRows = 20.

SQL = select * from table1 where c2 = ? …., parameter = ‘abc’, rowStart = 11, maxRows = 20.

 

當table1的任何數據對象(任何字段)改變、增加、刪除的時候,這些Query Key對應的結果集都不能確保沒有發生變化。很難做到根據數據對象的改變精確判斷哪些Query Key對應的結果集受到影響。最簡單的實現方法,就是清空任何SQL包含table1的Query Key。

 

(2) Query緩存中,Query Key對應的是數據對象列表,假如不同的Query Key對應的數據對象列表有交集,那麼,交集部分的數據對象就是重複存儲的。

 

比如,Query Key 1對應的數據對象列表為{a(id = 1), b(id = 2)},Query Key 2對應的數據對象列表為{a(id = 1), c(id = 3)},這個a就在兩個List同時存在了兩份。

 

4.二級緩存和Query緩存同步的困惑

假如,Query緩存中,一個Query Key對應的結果列表為{a (id = 1) , b (id = 2), c (id = 3)}; 二級緩存裏麵有也id = 1對應的數據對象a。

 

這兩個數據對象a之間是什麼關係?能夠保持狀態同步嗎?我閱讀Hibernate的相關源碼,沒有發現兩個緩存之間的這種同步關係。或兩者之間毫無關係。就像我上麵所說的,隻要表數據發生變化,相關的Query Key都要被清空。所以不用考慮同步問題?

 

 

https://www.idcnews.net/html/edu/20080403/258894.html

 

 

 

最後更新:2017-04-02 06:51:19

  上一篇:go 如何在Web.config中注冊用戶控件和自定義控件
  下一篇:go NoSQL數據庫筆談