在許多項目應用中,我們設計的數據庫中的一些表中的數據變化的頻率很慢,比如,我們有個GameInformation表保存所有已上線的游戲的信息,這個表中的數據變動的頻率就很小(因為可能一兩個月才會有個新游戲上線或偶爾修改一下已上線游戲的具體信息(通常都是不需緊急更新的)),而且,這個表中的數據又經常被用到,比如根據GameID獲取游戲的名字、簡介等等。這種表就很適合緩存在內存中,這樣可以提供更好的性能和有效地降低數據庫的負載。
DataRabbit.Application.Cache命名空間提供了對Entity緩存的支持,并且能夠定時刷新緩存(如每隔15分鐘刷新一次)。
首先,在框架中,Entity緩存(EntityCache)是通用Cache的一種,我們來看看,框架對緩存(ESBasic.Cache.ICache接口)的定義:
其次,ESBasic.Cache命名空間下有個ICacheManager,它用于管理所有緩存(Cache)實例,而且定時刷新每個緩存的功能也是它提供的。其接口定義如下:
現在,有了基礎緩存接口和緩存管理器的支持,我們就可以在其基礎上實作實體緩存(EntityCache)。
首先,一個實體Entity要能被緩存,該Entity必須實現ICachedEntity泛型接口:
下面舉一個例子來說明實體緩存的應用。
比如,我需要緩存所有啟用的GameInformation。
首先,讓GameInformation實體類從ICachedEntity繼承:
接下來,從DataRabbit.Application.Cache.EntityCache繼承得到具體的緩存類GameInfoCache:
如此即可。上述的介紹不僅用到的DataRabbit中的類,而且也用到了ESBasic中的相關組件,不用擔心,我在 DataRabbit 輕量的ORM框架(00) -- 序 一文的末尾提供的DataRabbit3.0下載中包含了必須的ESBasic動態庫。可以從那里下載,來試試EntityCache的方便性。
DataRabbit.Application.Cache命名空間提供了對Entity緩存的支持,并且能夠定時刷新緩存(如每隔15分鐘刷新一次)。
首先,在框架中,Entity緩存(EntityCache)是通用Cache的一種,我們來看看,框架對緩存(ESBasic.Cache.ICache接口)的定義:
public
interface
ICache
{
bool Enabled{ get ; set ;}
void Initialize();
void Refresh();
event CbSimple CacheRefreshed;
}
{
bool Enabled{ get ; set ;}
void Initialize();
void Refresh();
event CbSimple CacheRefreshed;
}
其次,ESBasic.Cache命名空間下有個ICacheManager,它用于管理所有緩存(Cache)實例,而且定時刷新每個緩存的功能也是它提供的。其接口定義如下:
public
interface
ICacheManager
{
/// <summary>
/// RefreshSpanInSecs定時刷新緩存的時間間隔
/// </summary>
int RefreshSpanInSecs{ set ;}
IList < ICache > CacheList{ set ;}
void Initialize();
void RefreshNow();
void AddCache(ICachecache);
void RemoveCache(ICachecache);
void RemoveCaches();
event CbCacheExceptionCacheRefreshFailed;
}
ESBasic.Cache.CacheManager類實現了該接口。
{
/// <summary>
/// RefreshSpanInSecs定時刷新緩存的時間間隔
/// </summary>
int RefreshSpanInSecs{ set ;}
IList < ICache > CacheList{ set ;}
void Initialize();
void RefreshNow();
void AddCache(ICachecache);
void RemoveCache(ICachecache);
void RemoveCaches();
event CbCacheExceptionCacheRefreshFailed;
}
現在,有了基礎緩存接口和緩存管理器的支持,我們就可以在其基礎上實作實體緩存(EntityCache)。
首先,一個實體Entity要能被緩存,該Entity必須實現ICachedEntity泛型接口:
///
<summary>
/// ICachedEntity可以被緩存的Entity
/// </summary>
/// <typeparamname="TPKey"> 主鍵的類型 </typeparam>
public interface ICachedEntity < TPKey >
{
TPKeyGetID();
}
那么,實體緩存可以提供哪些操作了?簡單想一下,我們就可以知道,比如獲取所有緩存的Entity,根據ID獲取Entity,等等。IEntityCache接口中定義了這些功能:
/// ICachedEntity可以被緩存的Entity
/// </summary>
/// <typeparamname="TPKey"> 主鍵的類型 </typeparam>
public interface ICachedEntity < TPKey >
{
TPKeyGetID();
}
///
<summary>
/// IEntityCache從數據庫中獲取符合條件的Entity并緩存起來。2007.07.07
/// </summary>
/// <typeparamname="TPKey"> 對應的數據表的主鍵類型 </typeparam>
/// <typeparamname="TEntity"> Entity類型 </typeparam>
public interface IEntityCache< TPKey,TEntity > : ICache where TEntity: class , ICachedEntity < TPKey >
{
/// <summary>
/// GetEntity獲取目標Entity,如果緩存中不存在,則刷新緩存,如果還招不到,則返回null。
/// </summary>
TEntityGetEntity(TPKeyentityID);
IList < TEntity > GetEntityList();
TransactionScopeFactoryTransactionScopeFactory{ set ;}
CacheRefreshMode CacheRefreshMode{ set ;}
}
/// <summary>
/// CacheRefreshMode緩存刷新模式:全部替換、增量。
/// </summary>
public enum CacheRefreshMode
{
ReplaceAll,
Increasement
}
DataRabbit.Application.Cache.EntityCache類實現了該接口,并且提供了虛方法CreateFilterTree來讓派生類來提供一系列條件,只有符合這些條件的Entity才會從數據庫中取出來緩存。CreateFilterTree方法定義如下:
/// IEntityCache從數據庫中獲取符合條件的Entity并緩存起來。2007.07.07
/// </summary>
/// <typeparamname="TPKey"> 對應的數據表的主鍵類型 </typeparam>
/// <typeparamname="TEntity"> Entity類型 </typeparam>
public interface IEntityCache< TPKey,TEntity > : ICache where TEntity: class , ICachedEntity < TPKey >
{
/// <summary>
/// GetEntity獲取目標Entity,如果緩存中不存在,則刷新緩存,如果還招不到,則返回null。
/// </summary>
TEntityGetEntity(TPKeyentityID);
IList < TEntity > GetEntityList();
TransactionScopeFactoryTransactionScopeFactory{ set ;}
CacheRefreshMode CacheRefreshMode{ set ;}
}
/// <summary>
/// CacheRefreshMode緩存刷新模式:全部替換、增量。
/// </summary>
public enum CacheRefreshMode
{
ReplaceAll,
Increasement
}
#region
CreateFilterTree
/// <summary>
/// SetFilterTree派生類可以通過此方法設置要緩存的對象的條件,返回null,表示緩存表中的所有Entity
/// </summary>
protected virtual IFilterTree CreateFilterTree()
{
return null ;
}
#endregion
/// <summary>
/// SetFilterTree派生類可以通過此方法設置要緩存的對象的條件,返回null,表示緩存表中的所有Entity
/// </summary>
protected virtual IFilterTree CreateFilterTree()
{
return null ;
}
#endregion
下面舉一個例子來說明實體緩存的應用。
比如,我需要緩存所有啟用的GameInformation。
首先,讓GameInformation實體類從ICachedEntity繼承:
public
partial
class
GameInformation
:
ICachedEntity
<
string
>
{
//
}
GameInformation表的主鍵ID是字符串類型。
{
//

}
接下來,從DataRabbit.Application.Cache.EntityCache繼承得到具體的緩存類GameInfoCache:
public
class
GameInfoCache
:
EntityCache
<
string
,GameInformation
>
{
protected override IFilterTreeCreateFilterTree()
{
// 取出所有啟用的游戲信息
return new SimpleFilterTree(LogicType.And, new Filter(GameInformation._Enabled, true ));
}
}
最后,我們通過Spring.net來配置緩存管理器和實體緩存即可,假設我們讓緩存管理器每15分鐘(900s)刷新一次。
{
protected override IFilterTreeCreateFilterTree()
{
// 取出所有啟用的游戲信息
return new SimpleFilterTree(LogicType.And, new Filter(GameInformation._Enabled, true ));
}
}
<
object
name
=
"g
ameInfoCache
"
type
=
"
GameRabbit.Entity.Cache.
GameInfoCache
,GameRabbit.Entity
"
init
-
method
=
"
Initialize
"
>
< propertyname = " Enabled " value = " true " />
< propertyname = " TransactionScopeFactory " ref = " transactionScopeFactory " />
< propertyname = " CacheRefreshMode " value = " ReplaceAll " />
</ object >
< object name = " cacheManager " type = " ESBasic.Cache.CacheManager,ESBasic " init - method = " Initialize " >
< propertyname = " RefreshSpanInSecs " value = "900 " />
< propertyname = " CacheList " >
< listelement - type = " ESBasic.Cache.ICache,ESBasic " >
< ref object = " g ameInfoCache " />
</ list >
</ property >
</ object >
< propertyname = " Enabled " value = " true " />
< propertyname = " TransactionScopeFactory " ref = " transactionScopeFactory " />
< propertyname = " CacheRefreshMode " value = " ReplaceAll " />
</ object >
< object name = " cacheManager " type = " ESBasic.Cache.CacheManager,ESBasic " init - method = " Initialize " >
< propertyname = " RefreshSpanInSecs " value = "900 " />
< propertyname = " CacheList " >
< listelement - type = " ESBasic.Cache.ICache,ESBasic " >
< ref object = " g ameInfoCache " />
</ list >
</ property >
</ object >
如此即可。上述的介紹不僅用到的DataRabbit中的類,而且也用到了ESBasic中的相關組件,不用擔心,我在 DataRabbit 輕量的ORM框架(00) -- 序 一文的末尾提供的DataRabbit3.0下載中包含了必須的ESBasic動態庫。可以從那里下載,來試試EntityCache的方便性。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
