标签:
源码下载地址: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;
}
标签:
原文地址:http://www.cnblogs.com/xiaoxiaojia/p/5314207.html