當前位置:首頁 » 硬碟大全 » 全局緩存類定義
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

全局緩存類定義

發布時間: 2022-10-09 12:03:57

㈠ 如何全局緩存access token java

如何全局緩存access token java
3.5 字元型數據
字元型數據包括字元常量和字元變數。
3.5.1 字元常量
字元常量是用單引號括起來的一個字元。
例如:
'a'、'b'、'='、'+'、'?'
都是合法字元常量。
在C語言中,字元常量有以下特點:
1) 字元常量只能用單引號括起來,不能用雙引號或其它括弧。
2) 字元常量只能是單個字元,不能是字元串。
3) 字元可以是字元集中任意字元。但數字被定義為字元型之後就不能參與數值運算。如'5'和5 是不同的。'5'是字元常量,不能參與運算。

㈡ 怎樣全局緩存access

全局緩存access代碼:<?php
class access
{
/**
* 聲明存儲查詢結果ID的數組,資料庫連接ID,存儲分頁信息的數組,緩存數據讀取偏移量
*/
public $resultId, $linkId, $pageMsg, $offset;
/**
* 聲明顯示錯誤消息的頁面地址
*/
public $errPage = '';
/**
* 聲明資料庫路徑,此路徑需為絕對路徑
*/
public $dbPath = '';

/**
* 緩存存儲路徑
*/
public $cachePath = '';

/**
* 緩存聲明周期,設為0則不適用緩存
*/
public $cacheLifeTime = 3600;

/**
* 當使用分頁查詢時,最多緩存多少頁
*/
public $cacheLimitMax = 100;

/**
* 建立資料庫連接
*
* 說明:
* 此資料庫類無構造函數,在聲明新類之後,需手動運行此函數
*/
public function connect()
{
$dsn = 'DRIVER={Microsoft Access Driver (*.mdb)}; DBQ='.$this->dbPath;
$this->linkId = odbc_connect($dsn,'','',sql_CUR_USE_ODBC);
$this->linkId || $this->setError('Connect database defeat!');
}

/**
* 執行一條SQL語句
*
* 參數:
* $sql 要執行的SQL語句
* $resultId 查詢結果的ID,當執行一條不需返回的SQL語句,如刪除,更新等時,該參數可省略
*/
public function query($sql ,$resultId = '__id__')
{
$this->resultId[$resultId] = odbc_exec($this->linkId,$sql);
$this->resultId[$resultId] || $this->setError('Carries out the SQL defeat!');
}

/**
* 從查詢結果集中讀取一條記錄,並返回為數組
*
* 參數:
* $resultId 查詢結果的ID
*/
public function record($resultId)
{
if (is_array($this->resultId[$resultId]))
{
$offset = $this->offset[$resultId]; $this->offset[$resultId]++;
return $this->resultId[$resultId][$offset];
}
return odbc_fetch_array($this->resultId[$resultId]);
}

/**
* 從查詢結果集中讀取一條記錄,並注冊為類的屬性,屬性名為欄位名
*
* 參數:
* $resultId 查詢結果ID
*/
public function recordObj($resultId)
{
if (is_array($this->resultId[$resultId]))
{
$rowArray = $this->resultId[$resultId][$this->offset[$resultId]];
$this->offset[$resultId]++;
} else {
$rowArray = $this->record($resultId);
}
for (reset($rowArray);$key = key($rowArray);next($rowArray)) $this->$key = $rowArray[$key];
}

/**
* 獲取一個查詢結果集的記錄數
*
* 參數:
* $resultId 查詢結果ID
*/
public function rowsNum($resultId)
{
return odbc_num_rows($this->resultId[$resultId]);
}

㈢ ThinkPHP中關於靜態緩存的定義格式為全局的操作靜態規則

ThinkPHP內置了靜態緩存的功能,並且支持靜態緩存的規則定義。
要使用靜態緩存功能,需要開啟HTML_CACHE_ON 參數,並且使用HTML_CACHE_RULES配置參數設置靜態緩存規則文件 。
靜態規則的定義方式如下:
'HTML_CACHE_ON'=>true,
'HTML_CACHE_RULES'=> array(
'ActionName' => array('靜態規則', '靜態緩存有效期', '附加規則'),
'MoleName(小寫)' => array('靜態規則', '靜態緩存有效期', '附加規則'),
'MoleName(小寫):ActionName' => array('靜態規則', '靜態緩存有效期', '附加規則'),
'*' => array('靜態規則', '靜態緩存有效期', '附加規則'),
//…更多操作的靜態規則
)
靜態緩存文件的根目錄在HTML_PATH 定義的路徑下面,並且只有定義了靜態規則的操作才會進行靜態緩存,注意,靜態規則的定義有三種方式:
第一種是定義全局的操作靜態規則,例如定義所有的read操作的靜態規則為
'read'=>array('{id}','60')

其中,{id} 表示取$_GET['id'] 為靜態緩存文件名,第二個參數表示緩存60秒
第二種是定義全局的模塊靜態規則,例如定義所有的User模塊的靜態規則為
'user:'=>array('User/{:action}_{id}','600')

其中,{:action} 表示當前的操作名稱 靜態
第三種是定義某個模塊的操作的靜態規則,例如,我們需要定義Blog模塊的read操作進行靜態緩存
'blog:read'=>array('{id}',0)
有個別特殊的規則,例如空模塊和空操作的靜態規則的定義,可以使用下面的方式:
'empty:index'=>array('{:mole}_{:action}',0) // 定義空模塊的靜態規則
'User:_empty'=>array('User/{:action}',0) // 定義空操作的靜態規則
第四種方式是定義全局的靜態緩存規則,這個屬於特殊情況下的使用,任何模塊的操作都適用,例如
'*'=>array('{$_SERVER.REQUEST_URI|md5}'),
根據當前的URL進行緩存

靜態規則是用於定義要生成的靜態文件的名稱,寫法可以包括以下情況
1、使用系統變數 包括 _GET _REQUEST _SERVER _SESSION _COOKIE
格式:
{$_×××|function}
例如:
{$_GET.name} {$_SERVER. REQUEST_URI|md5}
2、使用框架特定的變數
例如:{:app}、{:group} 、{:mole} 和{:action} 分別表示當前項目名、分組名、模塊名和操作名

3、使用_GET變數
{var|function}
也就是說 {id} 其實等效於 {$_GET.id}

4、直接使用函數
{|function}
例如:{|time}

5、支持混合定義,例如我們可以定義一個靜態規則為:
'{id},{name|md5}'
在{}之外的字元作為字元串對待,如果包含有」/」,會自動創建目錄。
例如,定義下面的靜態規則:
{:mole}/{:action}_{id}
則會在靜態目錄下面創建模塊名稱的子目錄,然後寫入操作名_id.shtml 文件。

靜態有效時間 單位為秒如果不定義,則會獲取配置參數HTML_CACHE_TIME 的設置值,如果定義為0則表示永久緩存。
附加規則通常用於對靜態規則進行函數運算,例如
'read'=>array('Think{id},{name}','60', 'md5')
翻譯後的靜態規則是 md5('Think'.$_GET['id']. ', '.$_GET['name']);
和靜態緩存相關的配置參數包括:
HTML_CACHE_ON 是否開啟靜態緩存功能
HTML_FILE_SUFFIX 靜態文件後綴 慣例配置的值是 .html
HTML_CACHE_TIME 默認的靜態緩存有效期 默認60秒 可以在靜態規則定義覆蓋

㈣ 定義一個全局數據作為緩存,在運算部分隨時往數據里寫數據,循環保存,這個怎麼修改程序啊只是加入這個東西

許多人認為,「緩存」是內存的一部分

許多技術文章都是這樣教授的

但是還是有很多人不知道緩存在什麼地方,緩存是做什麼用的

其實,緩存是CPU的一部分,它存在於CPU中

CPU存取數據的速度非常的快,一秒鍾能夠存取、處理十億條指令和數據(術語:CPU主頻1G),而內存就慢很多,快的內存能夠達到幾十兆就不錯了,可見兩者的速度差異是多麼的大

緩存是為了解決CPU速度和內存速度的速度差異問題

內存中被CPU訪問最頻繁的數據和指令被復制入CPU中的緩存,這樣CPU就可以不經常到象「蝸牛」一樣慢的內存中去取數據了,CPU只要到緩存中去取就行了,而緩存的速度要比內存快很多

這里要特別指出的是:
1.因為緩存只是內存中少部分數據的復製品,所以CPU到緩存中尋找數據時,也會出現找不到的情況(因為這些數據沒有從內存復制到緩存中去),這時CPU還是會到內存中去找數據,這樣系統的速度就慢下來了,不過CPU會把這些數據復制到緩存中去,以便下一次不要再到內存中去取。

2.因為隨著時間的變化,被訪問得最頻繁的數據不是一成不變的,也就是說,剛才還不頻繁的數據,此時已經需要被頻繁的訪問,剛才還是最頻繁的數據,現在又不頻繁了,所以說緩存中的數據要經常按照一定的演算法來更換,這樣才能保證緩存中的數據是被訪問最頻繁的

3.關於一級緩存和二級緩存
為了分清這兩個概念,我們先了解一下RAM

ram和ROM相對的,RAM是掉電以後,其中才信息就消失那一種,ROM在掉電以後信息也不會消失那一種

RAM又分兩種,

一種是靜態RAM,SRAM;一種是動態RAM,DRAM。前者的存儲速度要比後者快得多,我們現在使用的內存一般都是動態RAM。

有的菜鳥就說了,為了增加系統的速度,把緩存擴大不就行了嗎,擴大的越大,緩存的數據越多,系統不就越快了嗎

緩存通常都是靜態RAM,速度是非常的快,

但是靜態RAM集成度低(存儲相同的數據,靜態RAM的體積是動態RAM的6倍),

價格高(同容量的靜態RAM是動態RAM的四倍),

由此可見,擴大靜態RAM作為緩存是一個非常愚蠢的行為,

但是為了提高系統的性能和速度,我們必須要擴大緩存,

這樣就有了一個折中的方法,不擴大原來的靜態RAM緩存,而是增加一些高速動態RAM做為緩存,

這些高速動態RAM速度要比常規動態RAM快,但比原來的靜態RAM緩存慢,

我們把原來的靜態ram緩存叫一級緩存,而把後來增加的動態RAM叫二級緩存。

一級緩存和二級緩存中的內容都是內存中訪問頻率高的數據的復製品(映射),它們的存在都是為了減少高速CPU對慢速內存的訪問。
通常CPU找數據或指令的順序是:先到一級緩存中找,找不到再到二級緩存中找,如果還找不到就只有到內存中找了

㈤ Hibernate的一級緩存和二級緩存分別是什麼

Hibernate的緩存包括Session的緩存和SessionFactory的緩存,其中
SessionFactory的緩存又可以分為兩類:內置緩存和外置緩存。Session的緩
存是內置的,不能被卸載,也被稱為Hibernate的第一級緩存。
SessionFactory的內置緩存和Session的緩存在實現方式上比較相似,前者是
SessionFactory對象的一些集合屬性包含的數據,後者是指Session的一些集
合屬性包含的數據。SessionFactory的內置緩存中存放了映射元數據和預定義
SQL語句,映射元數據是映射文件中數據的拷貝,而預定義SQL語句是在
Hibernate初始化階段根據映射元數據推導出來,SessionFactory的內置緩存
是只讀的,應用程序不能修改緩存中的映射元數據和預定義SQL語句,因此
SessionFactory不需要進行內置緩存與映射文件的同步。SessionFactory的
外置緩存是一個可配置的插件。在默認情況下,SessionFactory不會啟用這個
插件。外置緩存的數據是資料庫數據的拷貝,外置緩存的介質可以是內存或者硬
盤。SessionFactory的外置緩存也被稱為Hibernate的第二級緩存。

㈥ fancycache

FancyCache是一個可以將系統內存或快閃記憶體虛擬成硬碟緩存的軟體。它把從硬碟中讀取的數據存入系統內存或快閃記憶體,使系統在下次訪問該數據時可以很快從內存讀取,避免再次讀取速度較慢的硬碟,從而突破硬碟瓶頸,提升系統性能。 FancyCache還具有檢測和利用系統未識別內存的功能,解決32位Windows操作系統無法完全使用4G或更多內存的問題。通過將檢測到的系統未識別內存用作硬碟緩存的方式,FancyCache使計算機可以利用全部安裝的內存。

FancyCache為硬碟分配內存作緩存,並攔截系統發送至硬碟的IO請求。如果IO請求讀取的數據已經在緩存中,則直接讀取緩存中的數據並完成IO請求。否則數據則從硬碟中讀取出來,並存入緩存,同時完成IO請求。由此可見,從緩存讀取的數據量越多,則系統性能提升的越多。

編輯本段主要特性
支持 LRU (最近最少使用調度演算法) 和LFU (最近最不常用調度演算法) 緩存演算法, 支持 讀寫緩存、僅讀緩存和僅寫緩存 三種緩存策略, 支持 直接寫入 和 延遲寫入 兩種寫入模式, 支持 系統內存、系統未識別內存、快閃記憶體檔、固態硬碟SSD作為緩存, 支持對分區或整個硬碟緩存, 支持 TRIM 指令, 支持可視化性能監視統計, 支持動態硬碟, 支持NTFS junction point (符號連接), 支持自定義文件系統, 支持即插即用。
編輯本段為什麼使用FancyCache?
Windows操作系統本身已經實現了基於文件的緩存系統,我們還需要再使用一個緩存系統FancyCache嗎? 某些應用程序會繞過Windows操作系統自身的緩存系統; Windows操作系統的緩存系統是基於全局進行緩存,即對所有數據進行緩存,而FancyCache可以根據用戶需要,設置僅對某一特定分區進行緩存。在同等緩存容量下,後者將更具目標性,從而提高緩存命中率。 FancyCache可以識別系統未識別內存,將其利用作緩存; FancyCache可以將快閃記憶體檔或SSD固態硬碟用作緩存,提升普通硬碟的訪問能力。
編輯本段軟體截圖

編輯本段支持的操作系統
Windows XP, Windows 2003, Windows Vista, Windows 2008, Windows 7, Windows 2008 R2
編輯本段FancyCache正進行Beta測試!
FancyCache Beta測試版本 0.7.2 已經發布。如果您有時間並願參與我們的測試,我們表示非常感謝! 測試版本有效期為3個月,可以從以下地址獲取, 分區版(可對每個分區緩存):最新版本為 (beta 版本 0.7.2) 包含 簡體中文語言包 硬碟版(可對整個硬碟緩存):最新版本為 (beta 版本 0.7.2) 包含 簡體中文語言包 強烈建議您在非實際生產和工作環境中測試beta版本軟體,以免造成不必要的損失,盡管當前版本已是比較穩定版本。同時Beta測試者請注意在測試之前對重要文件和數據先進行備份,以防萬一。如遇系統無法啟動等致命問題,用戶可以嘗試進入安全模式卸載軟體。

㈦ 緩存的定義是什麼

其實和電腦上緩存的概念是一樣的 緩存它充當一個緩沖的作用,因為內存與CPU的速度是不一致的,內存比CPU慢上好多倍,在處理數據時,沒有緩存,將會大大浪費CPU的資源,而緩存的速度接近於CPU,在處理數據的時候,系統將內存里的信息先存在緩存上,然後CPU從緩存內讀取數據的速度就會很快,大大的提升了系統的性能 但時間長, 緩存是就會儲存許多過去的信息而佔用大量空間,所以需要你清理

㈧ Okhttp解析(五)緩存的處理

大家好,之前我們講解了Okhttp網路數據請求相關的內容,這一節我們講講數據緩存的處理。本節按以下內容講解Okhttp緩存相關的內容。

緩存的使用場景很多,通過它可以將數據通過一定的規則存儲起來,再次請求數據的時候就可以快速從緩存中讀取了,緩存有以下優勢。

HTTP本身提供了一套緩存相關的機制。這套機制定義了相關的欄位和規則,用來客戶端和服務端進行緩存相關的協商,如響應的數據是否需要緩存,緩存有效期,緩存是否有效,伺服器端給出指示,而客戶端則根據服務端的指示做具體的緩存更新和讀取緩存工作。http緩存可以分為兩類:

強制緩存,在緩存數據未失效的情況下,可以直接使用緩存數據,有兩個欄位Expires和Cache-Control用於標明失效規則。

表示過期時間,由服務端返回。那麼下次請求數據時,判斷這個Expires過期時間是否已經過了,如果還沒有到過期時間,則使用緩存,如果過了過期時間,則重新請求伺服器的數據。Expires格式如下:

不過因為伺服器和客戶端的時間並不是同步的,用一個絕對時間作為過期的標記並不是很明智,所以HTTP1.1之後更多的是Cache-Control,它的控制更加靈活。

表示緩存的控制,有服務端返回。它有以下幾個取值:

默認情況下是private,也就是不能共享的。Cache-Control格式如下:

對比緩存,表示需要和服務端進行相關信息的對比,由伺服器決定是使用緩存還是最新內容,如果伺服器判定使用緩存,返回響應嗎304,判定使用最新內容,則返回響應碼200和最新數據。對比緩存的判定欄位有兩組:

ETag表示資源的一種標識信息,用於標識某個資源,由服務端返回,優先順序更高。格式如下:

然後客戶端再次請求時,加入欄位If-None-Match,格式如下:

服務端收到請求的該欄位時(之前的Etag值),和資源的唯一標識進行對比,如果相同,說明沒有改動,則返回狀態碼304,如果不同,說明資源被改過了,則返回狀態碼200和整個內容數據。

Last-Modified表示資源的最近修改時間,由服務端返回,優先順序更低。格式如下:

Last-Modified
由伺服器返回,表示響應的數據最近修改的時間。


If-Modified-Since
由客戶端請求,表示詢問伺服器這個時間是不是上次修改的時間。如果服務端該資源的修改時間小於等於If-Modified-Since指定的時間,說明資源沒有改動,返回響應狀態碼304,可以使用緩存。如果服務端該資源的修改時間大於If-Modified-Since指定的時間,說明資源又有改動了,則返回響應狀態碼200和最新數據給客戶端,客戶端使用響應返回的最新數據。

Last-Modified欄位的值(服務端返回的資源上次修改時間),常常被用於客戶端下次請求時的If-Modified-Since欄位中。

HTTP的緩存規則是優先考慮強制緩存,然後考慮對比緩存。

Okhttp緩存相關的類有如下:

要開啟使用Okhttp的緩存其實很簡單,只需要給OkHttpClient對象設置一個Cache對象即可,創建一個Cache時指定緩存保存的目錄和緩存最大的大小即可。

那麼下面我們來看看Okhttp緩存執行的大概流程

Okhttp的緩存流程分為讀取緩存和存儲緩存兩個過程,我們分別分析。

讀取使用緩存的流程從HttpEngine的sendRequest發送請求開始。

接下來我們分析

從Cache的get方法開始。它按以下步驟進行。

如果存在緩存的話,在指定的緩存目錄中,會有兩個文件「****.0」和「****.1」,分別存儲某個請求緩存的響應頭和響應體信息。(「****」是url的md5加密值)對應的ENTRY_METADATA響應頭和ENTRY_BODY響應體。緩存的讀取其實是由DiskLruCache來讀取的,DiskLruCache是支持Lru(最近最少訪問)規則的用於磁碟存儲的類,對應LruCache內存存儲。它在存儲的內容超過指定值之後,就會根據最近最少訪問的規則,把最近最少訪問的數據移除,以達到總大小不超過限制的目的。

接下來我們分析CacheStrategy緩存策略是怎麼判定的。

直接看CacheStrategy的get方法。緩存策略是由請求和緩存響應共同決定的。

接來下我們看看CacheControl類里有些什麼。

可以發現,它就是用於描述響應的緩存控制信息。

然後我們再看看Okhttp存儲緩存是怎麼進行的。

存儲緩存的流程從HttpEngine的readResponse發送請求開始的。

可以看到這里先通過maybeCache寫入了響應頭信息,再通過cacheWritingResponse寫入了響應體信息。我們再進去看Cache的put方法實現。

我們繼續看Cache的writeTo方法,可以看到是寫入一些響應頭信息。

到這里Okhttp緩存的讀取和存儲流程我們就清楚了。可以說,緩存的使用策略基本都是按照HTTP的緩存定義來實現的,所以對HTTP緩存相關欄位的理解是很重要的。然後關於DiskLruCache是如何管理緩存文件的,這個其實也很好理解,首先的原則就是按照LRU這種最近最少使用刪除的原則,當總的大小超過限定大小後,刪除最近最少使用的緩存文件,它的LRU演算法是使用LinkedHashMap進行維護的,這樣來保證,保留的緩存文件都是更常使用的。具體實現大家可以分析DiskLruCache和LinkedHashMap的實現原理。

㈨ hibernate緩存的詳細配置

很多人對二級緩存都不太了解,或者是有錯誤的認識,我一直想寫一篇文章介紹一下hibernate的二級緩存的,今天終於忍不住了。
我的經驗主要來自hibernate2.1版本,基本原理和3.0、3.1是一樣的,請原諒我的頑固不化。

hibernate的session提供了一級緩存,每個session,對同一個id進行兩次load,不會發送兩條sql給資料庫,但是session關閉的時候,一級緩存就失效了。

二級緩存是SessionFactory級別的全局緩存,它底下可以使用不同的緩存類庫,比如ehcache、oscache等,需要設置hibernate.cache.provider_class,我們這里用ehcache,在2.1中就是
hibernate.cache.provider_class=net.sf.hibernate.cache.EhCacheProvider
如果使用查詢緩存,加上
hibernate.cache.use_query_cache=true

緩存可以簡單的看成一個Map,通過key在緩存裡面找value。

Class的緩存
對於一條記錄,也就是一個PO來說,是根據ID來找的,緩存的key就是ID,value是POJO。無論list,load還是iterate,只要讀出一個對象,都會填充緩存。但是list不會使用緩存,而iterate會先取資料庫select id出來,然後一個id一個id的load,如果在緩存裡面有,就從緩存取,沒有的話就去資料庫load。假設是讀寫緩存,需要設置:
<cache usage="read-write"/>
如果你使用的二級緩存實現是ehcache的話,需要配置ehcache.xml
<cache name="com.xxx.pojo.Foo" maxElementsInMemory="500" eternal="false" timeToLiveSeconds="7200" timeToIdleSeconds="3600" overflowToDisk="true" />
其中eternal表示緩存是不是永遠不超時,timeToLiveSeconds是緩存中每個元素(這里也就是一個POJO)的超時時間,如果eternal="false",超過指定的時間,這個元素就被移走了。timeToIdleSeconds是發呆時間,是可選的。當往緩存裡面put的元素超過500個時,如果overflowToDisk="true",就會把緩存中的部分數據保存在硬碟上的臨時文件裡面。
每個需要緩存的class都要這樣配置。如果你沒有配置,hibernate會在啟動的時候警告你,然後使用defaultCache的配置,這樣多個class會共享一個配置。
當某個ID通過hibernate修改時,hibernate會知道,於是移除緩存。
這樣大家可能會想,同樣的查詢條件,第一次先list,第二次再iterate,就可以使用到緩存了。實際上這是很難的,因為你無法判斷什麼時候是第一次,而且每次查詢的條件通常是不一樣的,假如資料庫裡面有100條記錄,id從1到100,第一次list的時候出了前50個id,第二次iterate的時候卻查詢到30至70號id,那麼30-50是從緩存裡面取的,51到70是從資料庫取的,共發送1+20條sql。所以我一直認為iterate沒有什麼用,總是會有1+N的問題。
(題外話:有說法說大型查詢用list會把整個結果集裝入內存,很慢,而iterate只select id比較好,但是大型查詢總是要分頁查的,誰也不會真的把整個結果集裝進來,假如一頁20條的話,iterate共需要執行21條語句,list雖然選擇若干欄位,比iterate第一條select id語句慢一些,但只有一條語句,不裝入整個結果集hibernate還會根據資料庫方言做優化,比如使用mysql的limit,整體看來應該還是list快。)
如果想要對list或者iterate查詢的結果緩存,就要用到查詢緩存了

查詢緩存
首先需要配置hibernate.cache.use_query_cache=true
如果用ehcache,配置ehcache.xml,注意hibernate3.0以後不是net.sf的包名了
<cache name="net.sf.hibernate.cache.StandardQueryCache"
maxElementsInMemory="50" eternal="false" timeToIdleSeconds="3600"
timeToLiveSeconds="7200" overflowToDisk="true"/>
<cache name="net.sf.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="5000" eternal="true" overflowToDisk="true"/>
然後
query.setCacheable(true);//激活查詢緩存
query.setCacheRegion("myCacheRegion");//指定要使用的cacheRegion,可選
第二行指定要使用的cacheRegion是myCacheRegion,即你可以給每個查詢緩存做一個單獨的配置,使用setCacheRegion來做這個指定,需要在ehcache.xml裡面配置它:
<cache name="myCacheRegion" maxElementsInMemory="10" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200" overflowToDisk="true" />
如果省略第二行,不設置cacheRegion的話,那麼會使用上面提到的標准查詢緩存的配置,也就是net.sf.hibernate.cache.StandardQueryCache

對於查詢緩存來說,緩存的key是根據hql生成的sql,再加上參數,分頁等信息(可以通過日誌輸出看到,不過它的輸出不是很可讀,最好改一下它的代碼)。
比如hql:
from Cat c where c.name like ?
生成大致如下的sql:
select * from cat c where c.name like ?
參數是"tiger%",那麼查詢緩存的key*大約*是這樣的字元串(我是憑記憶寫的,並不精確,不過看了也該明白了):
select * from cat c where c.name like ? , parameter:tiger%
這樣,保證了同樣的查詢、同樣的參數等條件下具有一樣的key。
現在說說緩存的value,如果是list方式的話,value在這里並不是整個結果集,而是查詢出來的這一串ID。也就是說,不管是list方法還是iterate方法,第一次查詢的時候,它們的查詢方式很它們平時的方式是一樣的,list執行一條sql,iterate執行1+N條,多出來的行為是它們填充了緩存。但是到同樣條件第二次查詢的時候,就都和iterate的行為一樣了,根據緩存的key去緩存裡面查到了value,value是一串id,然後在到class的緩存裡面去一個一個的load出來。這樣做是為了節約內存。
可以看出來,查詢緩存需要打開相關類的class緩存。list和iterate方法第一次執行的時候,都是既填充查詢緩存又填充class緩存的。
這里還有一個很容易被忽視的重要問題,即打開查詢緩存以後,即使是list方法也可能遇到1+N的問題!相同條件第一次list的時候,因為查詢緩存中找不到,不管class緩存是否存在數據,總是發送一條sql語句到資料庫獲取全部數據,然後填充查詢緩存和class緩存。但是第二次執行的時候,問題就來了,如果你的class緩存的超時時間比較短,現在class緩存都超時了,但是查詢緩存還在,那麼list方法在獲取id串以後,將會一個一個去資料庫load!因此,class緩存的超時時間一定不能短於查詢緩存設置的超時時間!如果還設置了發呆時間的話,保證class緩存的發呆時間也大於查詢的緩存的生存時間。這里還有其他情況,比如class緩存被程序強制evict了,這種情況就請自己注意了。

另外,如果hql查詢包含select字句,那麼查詢緩存裡面的value就是整個結果集了。

當hibernate更新資料庫的時候,它怎麼知道更新哪些查詢緩存呢?
hibernate在一個地方維護每個表的最後更新時間,其實也就是放在上面net.sf.hibernate.cache.UpdateTimestampsCache所指定的緩存配置裡面。
當通過hibernate更新的時候,hibernate會知道這次更新影響了哪些表。然後它更新這些表的最後更新時間。每個緩存都有一個生成時間和這個緩存所查詢的表,當hibernate查詢一個緩存是否存在的時候,如果緩存存在,它還要取出緩存的生成時間和這個緩存所查詢的表,然後去查找這些表的最後更新時間,如果有一個表在生成時間後更新過了,那麼這個緩存是無效的。
可以看出,只要更新過一個表,那麼凡是涉及到這個表的查詢緩存就失效了,因此查詢緩存的命中率可能會比較低。

Collection緩存
需要在hbm的collection裡面設置
<cache usage="read-write"/>
假如class是Cat,collection叫children,那麼ehcache裡面配置
<cache name="com.xxx.pojo.Cat.children"
maxElementsInMemory="20" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200"
overflowToDisk="true" />
Collection的緩存和前面查詢緩存的list一樣,也是只保持一串id,但它不會因為這個表更新過就失效,一個collection緩存僅在這個collection裡面的元素有增刪時才失效。
這樣有一個問題,如果你的collection是根據某個欄位排序的,當其中一個元素更新了該欄位時,導致順序改變時,collection緩存裡面的順序沒有做更新。

緩存策略
只讀緩存(read-only):沒有什麼好說的
讀/寫緩存(read-write):程序可能要的更新數據
不嚴格的讀/寫緩存(nonstrict-read-write):需要更新數據,但是兩個事務更新同一條記錄的可能性很小,性能比讀寫緩存好
事務緩存(transactional):緩存支持事務,發生異常的時候,緩存也能夠回滾,只支持jta環境,這個我沒有怎麼研究過

讀寫緩存和不嚴格讀寫緩存在實現上的區別在於,讀寫緩存更新緩存的時候會把緩存裡面的數據換成一個鎖,其他事務如果去取相應的緩存數據,發現被鎖住了,然後就直接取資料庫查詢。
在hibernate2.1的ehcache實現中,如果鎖住部分緩存的事務發生了異常,那麼緩存會一直被鎖住,直到60秒後超時。
不嚴格讀寫緩存不鎖定緩存中的數據。

使用二級緩存的前置條件
你的hibernate程序對資料庫有獨占的寫訪問權,其他的進程更新了資料庫,hibernate是不可能知道的。你操作資料庫必需直接通過hibernate,如果你調用存儲過程,或者自己使用jdbc更新資料庫,hibernate也是不知道的。hibernate3.0的大批量更新和刪除是不更新二級緩存的,但是據說3.1已經解決了這個問題。
這個限制相當的棘手,有時候hibernate做批量更新、刪除很慢,但是你卻不能自己寫jdbc來優化,很郁悶吧。
SessionFactory也提供了移除緩存的方法,你一定要自己寫一些JDBC的話,可以調用這些方法移除緩存,這些方法是:
void evict(Class persistentClass)
Evict all entries from the second-level cache.
void evict(Class persistentClass, Serializable id)
Evict an entry from the second-level cache.
void evictCollection(String roleName)
Evict all entries from the second-level cache.
void evictCollection(String roleName, Serializable id)
Evict an entry from the second-level cache.
void evictQueries()
Evict any query result sets cached in the default query cache region.
void evictQueries(String cacheRegion)
Evict any query result sets cached in the named query cache region.
不過我不建議這樣做,因為這樣很難維護。比如你現在用JDBC批量更新了某個表,有3個查詢緩存會用到這個表,用evictQueries(String cacheRegion)移除了3個查詢緩存,然後用evict(Class persistentClass)移除了class緩存,看上去好像完整了。不過哪天你添加了一個相關查詢緩存,可能會忘記更新這里的移除代碼。如果你的jdbc代碼到處都是,在你添加一個查詢緩存的時候,還知道其他什麼地方也要做相應的改動嗎?

----------------------------------------------------

總結:
不要想當然的以為緩存一定能提高性能,僅僅在你能夠駕馭它並且條件合適的情況下才是這樣的。hibernate的二級緩存限制還是比較多的,不方便用jdbc可能會大大的降低更新性能。在不了解原理的情況下亂用,可能會有1+N的問題。不當的使用還可能導致讀出臟數據。
如果受不了hibernate的諸多限制,那麼還是自己在應用程序的層面上做緩存吧。
在越高的層面上做緩存,效果就會越好。就好像盡管磁碟有緩存,資料庫還是要實現自己的緩存,盡管資料庫有緩存,咱們的應用程序還是要做緩存。因為底層的緩存它並不知道高層要用這些數據干什麼,只能做的比較通用,而高層可以有針對性的實現緩存,所以在更高的級別上做緩存,效果也要好些吧。

㈩ thinkphp 靜態緩存的設置方法,怎麼設置thinkphp靜態頁

thinkphp默認是自動開啟模版緩存的。你可以在入口文件裡面把:
define
(
'runtime_path',
'./runtime/'
);這行代碼注釋掉