源碼下載地址:http://www.jinhusns.com/Products/Download/?type=xcj
五、 架構使用說明 > 緩存 > 使用說明 >
(一)基礎類庫介紹
ICacheService方法說明:
方法名稱 |
成員修飾 |
說明 |
備注 |
Add(多個參數):void +1重載 |
public static |
加入緩存項 |
|
Set(多個參數):void +1重載 |
public static |
添加或更新緩存 |
如果無對應緩存項則創建,否則更新 |
Remove(stringcacheKey):void |
public static |
移除緩存 |
|
MarkDeletion(多個參數):void |
public static |
標識為刪除 |
|
Clear():void |
public static |
清空緩存 |
|
Get(string cacheKey):object |
public static |
從緩存獲取 |
|
Get<T>(string cacheKey): T |
public static |
從緩存獲取 |
|
GetFromFirstLevel(stringcacheKey): object |
public static |
從一層緩存獲取 |
分布式緩存情況下從分布式緩存獲取 |
GetFromFirstLevel<T>(string cacheKey) : T |
public static |
從一層緩存獲取 |
分布式緩存情況下從分布式緩存獲取 |
1) 提供Tunynet.Caching.DefaultCacheService作為ICacheService的默認實現;
CacheSettingAttribute屬性說明:
屬性名稱 |
成員修飾 |
說明 |
備注 |
EnableCache: bool |
public |
是否啟用緩存 |
僅允許在構造器設置屬性 |
ExpirationPolicy : EntityCacheExpirationPolicies |
public |
實體緩存(實體正文緩存)過期策略 |
|
PropertyNameOfBody : string |
public |
實體正文緩存對應的屬性名稱(如果不需單獨存儲實體正文緩存,則不要設置該屬性) |
|
PropertyNamesOfArea : string |
public |
緩存分區的屬性名稱(可以設置多個,用逗號分隔) |
|
RealTimeCacheHelper方法說明:
方法名稱 |
成員修飾 |
說明 |
備注 |
GetGlobalVersion():long |
public |
列表緩存全局version |
|
GetEntityVersion(objectprimaryKey): long |
public |
獲取Entity的緩存版本 |
|
GetAreaVersion(多個參數): long |
public |
獲取列表緩存區域version |
|
GetCacheKeyOfEntity(object primaryKey): string |
public |
獲取實體的cacheKey |
|
GetListCacheKeyPrefix(多個參數): string |
public |
獲取列表緩存CacheKey的前綴(例如:abe3ds2sa90:8:) |
|
IncreaseEntityCacheVersion(object entityID): void |
public |
遞增實體緩存(僅更新實體時需要遞增) |
|
IncreaseListCacheVersion(IEntity entity): void |
public |
遞增列表緩存version(僅增加、刪除實體時需要遞增) |
|
IncreaseAreaVersion(多個參數): void +2重載 |
public |
遞增列表緩存區域version |
|
(二)緩存時間過期類型
1. 預設以下幾種過期時間(在Tunynet.Caching.CachingExpirationTypes定義);
緩存期限類型 |
描述 |
備注 |
Invariable |
永久不變的 |
|
Stable |
穩定數據 |
例如: Resources.xml、Area、Application |
RelativelyStable |
相對穩定 |
例如: 權限配置、審核配置、敏感詞、表情、站點類別、資訊版塊、資訊版塊集合 |
UsualSingleObject |
常用的單個對象 |
例如: 用戶、群組、類別、標簽、博客Section、相冊Section、論壇版塊、活動 |
UsualObjectCollection |
常用的對象集合 |
例如: 用戶的朋友 |
SingleObject |
單個對象 |
例如: 博文、帖子 |
ObjectCollection |
對象集合 |
例如: 用於分頁的私信數據 |
(三)緩存配置說明
緩存服務通過DI容器進行注冊,例如:
//注冊緩存
containerBuilder.Register(c => new DefaultCacheService(new RuntimeMemoryCache(), 1.0F)).As<ICacheService>().SingleInstance();
3. 如果自行實現ICacheService,同樣在此注冊替換掉DefaultCacheService;
(四)緩存開發注意事項
1) 需緩存的實體必須標注[Serializable];
2) 特殊數據類型必須驗證是否支持序列化/反序列化,例如從Dictionary<T key,T value>派生的類型無法直接序列化;
3. 不要在使用Repository.GetTopEntities(inttopNumber, CachingExpirationTypescachingExpirationTypes, Func<string>getCacheKey, Func<PetaPoco.Sql>generateSql)設置CacheKey時與topNumber相關,因為不管topNumber值是多少,實際都會最多獲取SecondaryMaxRecords條數據並緩存起來。即不同的topNumber可以共用一份緩存,用於提升緩存使用率,進而提升性能。
(五)實體的緩存標注
使用CacheSettingAttribute在實體上進行標注,使大部分緩存工作得以在Repository自動處理。
[CacheSetting(true, ExpirationPolicy = EntityCacheExpirationPolicies.Normal, PropertyNamesOfArea = "UserId,CategoryId", PropertyNameOfBody = "Body")]
[Serializable]
publicclassDiscussQuestion : IEntity
{
……
}
(六)使用實體正文緩存
當實體正文可能很大時,為了提升運行效率並減少分布式緩存時的網絡流量將實體正文緩存單獨存儲,並且不在實體緩存中存儲該部分內容。使用實體正文緩存,需要遵循以下步驟:
/// <summary>
///獲取DiscussQuestion內容
/// </summary>
public string GetBody(long questionId)
{
string cacheKey = RealTimeCacheHelper.GetCacheKeyOfEntityBody(questionId);
string body = cacheService.Get<string>(cacheKey);
if (body == null)
{
DiscussQuestion question = Database.SingleOrDefault<DiscussQuestion>(questionId);
body = question != null ? question.Body : string.Empty;
cacheService.Add(cacheKey, body, CachingExpirationType.SingleObject);
}
return body;
}
(七)列表緩存使用
列表緩存的主要工作是CacheKey的獲取。
StringBuilder cacheKey = new StringBuilder(CacheSetting.GetListCacheKeyPrefix(CacheVersionTypes.None));
cacheKey.AppendFormat("Ranking:sb-{0}", (int)sortBy);
return cacheKey.ToString();
1) 可以通過RealTimeCacheHelper的以下方法獲取列表緩存CacheKey前綴,直接使用第一個方法是最簡便的方式;
public string GetListCacheKeyPrefix(CacheVersionType cacheVersionType, string areaCachePropertyName, object areaCachePropertyValue);
2) 在使用查詢條件類並且需要即時性緩存時,可以使查詢條件類實現IListCacheSetting,例如:
///<summary>
/// DiscussQuestion查詢條件封裝
///</summary>
public class DiscussQuestionQuery : IListCacheSetting
{
public DiscussQuestionQuery(CacheVersionTypes cacheVersionType)
{
this.cacheVersionType = cacheVersionType;
}
……
#region IListCacheSetting 成員
Private CacheVersionTypes cacheVersionType = CacheVersionTypes.None;
///<summary>
///列表緩存版本設置
///</summary>
CacheVersionTypesIListCacheSetting.CacheVersionType
{
get { return cacheVersionType; }
}
private string areaCachePropertyName = null;
///<summary>
///緩存分區字段名稱
///</summary>
public string AreaCachePropertyName
{
get { return areaCachePropertyName; }
set { areaCachePropertyName = value; }
}
private object areaCachePropertyValue = null;
///<summary>
///緩存分區字段值
///</summary>
public object AreaCachePropertyValue
{
get { return areaCachePropertyValue; }
set { areaCachePropertyValue = value; }
}
#endregion
}
3) 可以自行定義的Repository使用以下代碼獲取CacheKey:
StringBuilder cacheKey = new StringBuilder(RealTimeCacheHelper.GetListCacheKeyPrefix(query));
if (query.UserId.HasValue)
cacheKey.AppendFormat("UserID-{0}:", query.UserId.Value);
cacheKey.AppendFormat("sb-{0}:", (int)query.SortBy);
return cacheKey.ToString();
4) 在Service中使用以下代碼構造DiscussQuestionQuery:
/// <summary>
/// 獲取我創建的問題
/// </summary>
public PagingDataSet<DiscussQuestion> GetMyQuestions(long userId, int pageIndex)
{
DiscussQuestionQuery query = new DiscussQuestionQuery(CacheVersionType.AreaVersion);
query.AreaCachePropertyName = "UserId";
query.AreaCachePropertyValue = userId;
query.UserId = userId;
return questionRepository.GetQuestions(query, QuestionPageSize, pageIndex);
}
(八)如何使用實體以外的屬性作為分區
使用實體以外的屬性作為分區時,無法依靠Repository自動維護對應分區緩存版本,需要通過代碼自行控制。
/// <summary>
/// 把用戶加入到一組角色中
/// </summary>
public void AddUserToRoles(int userID, List<int> roleIDs)
{
var sql_delete = PetaPoco.Sql.Builder.Append("DELETE FROM tn_UsersInRoles where UserID=@0", userID);
List<PetaPoco.Sql> sql_inserts = new List<PetaPoco.Sql>();
foreach (var roleID in roleIDs)
{
var sql_insert = PetaPoco.Sql.Builder.Append("INSERT INTO tn_UsersInRoles (UserID,RoleID) VALUES (@0,@1)", userID, roleID);
sql_inserts.Add(sql_insert);
}
using (var scope = Database.GetTransaction())
{
Database.Execute(sql_delete);
Database.Execute(sql_inserts);
scope.Complete();
}
//遞增緩存分區版本號(UserID)
RealTimeCacheHelper.IncreaseAreaVersion("UserID", userID);
}
/// <summary>
///獲取用戶的角色
/// </summary>
public IEnumerable<Role> GetRolesOfUser(int userID)
{
string cacheKey = RealTimeCacheHelper.GetListCacheKeyPrefix(CacheVersionTypes.AreaVersion, "UserID", userID);
IEnumerable<Role> roles = CacheService.Get<IEnumerable<Role>>(cacheKey);
if (roles == null)
{
var sql = PetaPoco.Sql.Builder
.Select("RoleID")
.From("tn_UsersInRoles")
.Where("UserID = @0", userID);
IList<object> roleIDs = Database.FetchFirstColumn(sql);
RoleRepository roleRepository = new RoleRepository();
roles = roleRepository.PopulateEntitiesByPrimaryKeys(roleIDs);
CacheService.Add(cacheKey, roles, CachingExpirationTypes.UsualObjectCollection);
}
return roles;
}
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。