系统缓存分为以下三种:
- 数据库缓存
- 应用服务器缓存
- 客户端缓存
数据库缓存
由于数据库使用的是Oracle11g,所以可以使用对应的结果缓存。结果缓存有两种使用方法。如果想在select语句中使用可在select后面跟上加上/*+ result_cache */ 代码如下:
select /*+ result_cache */ count(1) from kg_biaokaxx;
对于一些词语的取值可以通过函数实现,函数中加入result_cache来使用缓存,可直接使用COMMON_GetWordsContent函数查询词语数据,不必在使用left join关联词语表(当时测过性能,大数据量需要查词语时使用函数会慢很多,但现在使用了缓存就不会了)。
函数代码如下:
CREATE OR REPLACE FUNCTION COMMON_GetWordsContent
--------------------------------------------------------------------------------------
-- Create By:zhangyi@shanghai3h.com
-- Create Date: 2012-05-27
-- Sample:
-- Description: 根据类型,所属大类和词语值获取对应的词语名称,
-- 1:系统词语 2:用户词语
------------------------------------------------------------------------------------
(V_LeiXing integer,V_BelongID integer,V_WordsValue varchar2)
return varchar2
result_cache relies_on (S_Words,CY_YONGHUPZ)
is
V_WordsContent varchar2(500);
BEGIN
V_WordsContent :='';
if V_LeiXing = 1 then
SELECT WordsContent INTO V_WordsContent
FROM S_Words WHERE
WordsValue = V_WordsValue
AND BelongID = V_BelongID ;
else
SELECT S_CANSHUMC INTO V_WordsContent
FROM CY_YONGHUPZ WHERE
S_CANSHUZ = V_WordsValue
AND I_LiShuID = V_BelongID ;
end if;
RETURN( V_WordsContent);
END COMMON_GetWordsContent;
--------------------------------------------------------------------------------------
-- Create By:zhangyi@shanghai3h.com
-- Create Date: 2012-05-27
-- Sample:
-- Description: 根据类型,所属大类和词语值获取对应的词语名称,
-- 1:系统词语 2:用户词语
------------------------------------------------------------------------------------
(V_LeiXing integer,V_BelongID integer,V_WordsValue varchar2)
return varchar2
result_cache relies_on (S_Words,CY_YONGHUPZ)
is
V_WordsContent varchar2(500);
BEGIN
V_WordsContent :='';
if V_LeiXing = 1 then
SELECT WordsContent INTO V_WordsContent
FROM S_Words WHERE
WordsValue = V_WordsValue
AND BelongID = V_BelongID ;
else
SELECT S_CANSHUMC INTO V_WordsContent
FROM CY_YONGHUPZ WHERE
S_CANSHUZ = V_WordsValue
AND I_LiShuID = V_BelongID ;
end if;
RETURN( V_WordsContent);
END COMMON_GetWordsContent;
应用服务器缓存
由于系统使用了负载均衡,这部分的实现是通过微软企业库的Caching来实现的。在SQL Server中有现成的脚本可以使用。Oracle还没有空实验。应该也要对应的实现存储过程。对应的代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//********************************************************
//创建日期:<创建日期,2012-04-16>
//创建作者:<张易,zhangyi@shanghai3h.com>
//功能说明:缓存类:由于分布式的关系,使用数据库缓存。
// 配置在config中,需用脚本创建库以及对应的存储过程
//********************************************************
using System;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
namespace CSMS2.Infrastructure.Helpers
{
public static class CacheHelper
{
//2种建立CacheManager的方式
//ICacheManager cache = EnterpriseLibraryContainer.Current.GetInstance<ICacheManager>();
private static ICacheManager cache = CacheFactory.GetCacheManager();
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">键</param>
/// <param name="value">值</param>
/// <param name="isRefresh">是否刷新</param>
public static void Add(string key, object value, bool isRefresh = false)
{
if (isRefresh)
{
//自定义刷新方式,如果过期将自动重新加载,过期时间为5分钟
cache.Add(key, value, CacheItemPriority.Normal, new MyCacheItemRefreshAction(), new AbsoluteTime(TimeSpan.FromMinutes(5)));
}
else
{
cache.Add(key, value);
}
}
/// <summary>
/// 获取缓存对象
/// </summary>
/// <param name="key">键</param>
/// <returns></returns>
public static object GetCache(string key)
{
return cache.GetData(key);
}
/// <summary>
/// 移除缓存对象
/// </summary>
/// <param name="key">键</param>
public static void RemoveCache(string key)
{
cache.Remove(key);
}
}
/// <summary>
/// 自定义缓存刷新操作
/// </summary>
[Serializable]
public class MyCacheItemRefreshAction : ICacheItemRefreshAction
{
#region ICacheItemRefreshAction 成员
/// <summary>
/// 自定义刷新操作
/// </summary>
/// <param name="removedKey">移除的键</param>
/// <param name="expiredValue">过期的值</param>
/// <param name="removalReason">移除理由</param>
void ICacheItemRefreshAction.Refresh(string removedKey, object expiredValue, CacheItemRemovedReason removalReason)
{
if (removalReason == CacheItemRemovedReason.Expired)
{
ICacheManager cache = CacheFactory.GetCacheManager();
cache.Add(removedKey, expiredValue);
}
}
#endregion
}
}
//创建日期:<创建日期,2012-04-16>
//创建作者:<张易,zhangyi@shanghai3h.com>
//功能说明:缓存类:由于分布式的关系,使用数据库缓存。
// 配置在config中,需用脚本创建库以及对应的存储过程
//********************************************************
using System;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
namespace CSMS2.Infrastructure.Helpers
{
public static class CacheHelper
{
//2种建立CacheManager的方式
//ICacheManager cache = EnterpriseLibraryContainer.Current.GetInstance<ICacheManager>();
private static ICacheManager cache = CacheFactory.GetCacheManager();
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">键</param>
/// <param name="value">值</param>
/// <param name="isRefresh">是否刷新</param>
public static void Add(string key, object value, bool isRefresh = false)
{
if (isRefresh)
{
//自定义刷新方式,如果过期将自动重新加载,过期时间为5分钟
cache.Add(key, value, CacheItemPriority.Normal, new MyCacheItemRefreshAction(), new AbsoluteTime(TimeSpan.FromMinutes(5)));
}
else
{
cache.Add(key, value);
}
}
/// <summary>
/// 获取缓存对象
/// </summary>
/// <param name="key">键</param>
/// <returns></returns>
public static object GetCache(string key)
{
return cache.GetData(key);
}
/// <summary>
/// 移除缓存对象
/// </summary>
/// <param name="key">键</param>
public static void RemoveCache(string key)
{
cache.Remove(key);
}
}
/// <summary>
/// 自定义缓存刷新操作
/// </summary>
[Serializable]
public class MyCacheItemRefreshAction : ICacheItemRefreshAction
{
#region ICacheItemRefreshAction 成员
/// <summary>
/// 自定义刷新操作
/// </summary>
/// <param name="removedKey">移除的键</param>
/// <param name="expiredValue">过期的值</param>
/// <param name="removalReason">移除理由</param>
void ICacheItemRefreshAction.Refresh(string removedKey, object expiredValue, CacheItemRemovedReason removalReason)
{
if (removalReason == CacheItemRemovedReason.Expired)
{
ICacheManager cache = CacheFactory.GetCacheManager();
cache.Add(removedKey, expiredValue);
}
}
#endregion
}
}
客户端缓存
因为系统使用C/S模式,所以可以将数据缓存在客户端的内存中。我觉得这个使用起来蛮方便的,直接用个单例模式就可实现。也不会去定时刷新数据库。数据改变后,告诉客户CSMS关掉重开一下就可以了。
调用方法如下:
ClientCacheHelper.GetWordsByID(WordsType.开账分类);
ClientCacheHelper.GetYHWordsByID(YHWordsType.工次);
ClientCacheHelper.GetValueByKey(SettingType.金额小数位数);
ClientCacheHelper.GetYHWordsByID(YHWordsType.工次);
ClientCacheHelper.GetValueByKey(SettingType.金额小数位数);
目前只做了系统词语、用户词语、站点和键值对的缓存,需要时可以增加。当配置绑定使用时就变为了如下方法:
BindDataHelper.BindDropDownList(ClientCacheHelper.GetWordsByID(WordsType.开账分类), LueCH);
客户端缓存的代码如下:
//********************************************************
//创建日期:<创建日期,2012-05-29>
//创建作者:<张易,zhangyi@shanghai3h.com>
//功能说明:使用客户端缓存,将对应的表缓存到客户端
//在主窗体加载时调用,将常用的表加载到客户端,以后直接读取客户端缓存即可。
//********************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Data;
using CSMS2.Entity;
namespace CSMS2.Presentation.Common
{
public static class ClientCacheHelper
{
/// <summary>
/// Hashtalbe存储
/// </summary>
private static Hashtable hs = new Hashtable();
/// <summary>
/// 添加键值对
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public static void Add(string key, object value)
{
hs.Add(key, value);
}
/// <summary>
/// 静态构造函数
/// </summary>
static ClientCacheHelper()
{
AddTable();
}
/// <summary>
/// 获取系统词语
/// </summary>
/// <param name="belongID"></param>
/// <returns></returns>
public static DataTable GetWordsByID(WordsType belongID)
{
var lst = GetCache("S_WORDS") as S_WORDS[];
var l = lst.Where(s => s.BELONGID == Convert.ToInt32(belongID)).Select(s => new { key = s.WORDSCONTENT, value = s.WORDSVALUE });
return CSMS2.Infrastructure.Helpers.ConvertHelper.ToDataTable(l);
}
/// <summary>
/// 获取用户词语
/// </summary>
/// <param name="belongID"></param>
/// <returns></returns>
public static DataTable GetYHWordsByID(YHWordsType belongID)
{
var lst = GetCache("CY_YONGHUPZ") as CY_YONGHUPZ[];
var l = lst.Where(s => s.I_LISHUID == Convert.ToInt32(belongID)).Select(s => new { key = s.S_CANSHUMC, value = s.S_CANSHUZ });
return CSMS2.Infrastructure.Helpers.ConvertHelper.ToDataTable(l);
}
/// <summary>
/// 获取下级站点
/// </summary>
/// <param name="stationID"></param>
/// <returns></returns>
public static DataTable GetStationByID(StationType stationID)
{
var lst = GetCache("S_STATION") as S_STATION[];
var l = lst.Where(s => s.BELONGSTATION == stationID.ToString()).Select(s => new { key = s.STATIONNAME, value = s.STATIONID });
return CSMS2.Infrastructure.Helpers.ConvertHelper.ToDataTable(l);
}
/// <summary>
/// 根据键取值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetValueByKey(string key)
{
var lst = GetCache("S_SETTINGS") as S_SETTINGS[];
return lst.Where(s => s.KEYNAME == key).Select(s => s.CONFIGVALUE).First().ToString();
}
/// <summary>
/// 添加表,缓存用
/// </summary>
public static void AddTable()
{
CommonService.CommonClient common = new CommonService.CommonClient();
hs.Add("S_WORDS", common.GetAllWords());
hs.Add("CY_YONGHUPZ", common.GetAllYHWords());
hs.Add("S_SETTINGS", common.GetAllSettings());
hs.Add("S_STATION", common.GetAllStation());
common.Close();
}
/// <summary>
/// 获取缓存数据
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static object GetCache(string key)
{
if (null == hs[key])
{
hs.Clear();
AddTable();
}
return hs[key];
}
/// <summary>
/// 移除缓存对象
/// </summary>
/// <param name="key">键</param>
public static void RemoveCache(string key)
{
hs.Remove(key);
}
}
}
//创建日期:<创建日期,2012-05-29>
//创建作者:<张易,zhangyi@shanghai3h.com>
//功能说明:使用客户端缓存,将对应的表缓存到客户端
//在主窗体加载时调用,将常用的表加载到客户端,以后直接读取客户端缓存即可。
//********************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Data;
using CSMS2.Entity;
namespace CSMS2.Presentation.Common
{
public static class ClientCacheHelper
{
/// <summary>
/// Hashtalbe存储
/// </summary>
private static Hashtable hs = new Hashtable();
/// <summary>
/// 添加键值对
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public static void Add(string key, object value)
{
hs.Add(key, value);
}
/// <summary>
/// 静态构造函数
/// </summary>
static ClientCacheHelper()
{
AddTable();
}
/// <summary>
/// 获取系统词语
/// </summary>
/// <param name="belongID"></param>
/// <returns></returns>
public static DataTable GetWordsByID(WordsType belongID)
{
var lst = GetCache("S_WORDS") as S_WORDS[];
var l = lst.Where(s => s.BELONGID == Convert.ToInt32(belongID)).Select(s => new { key = s.WORDSCONTENT, value = s.WORDSVALUE });
return CSMS2.Infrastructure.Helpers.ConvertHelper.ToDataTable(l);
}
/// <summary>
/// 获取用户词语
/// </summary>
/// <param name="belongID"></param>
/// <returns></returns>
public static DataTable GetYHWordsByID(YHWordsType belongID)
{
var lst = GetCache("CY_YONGHUPZ") as CY_YONGHUPZ[];
var l = lst.Where(s => s.I_LISHUID == Convert.ToInt32(belongID)).Select(s => new { key = s.S_CANSHUMC, value = s.S_CANSHUZ });
return CSMS2.Infrastructure.Helpers.ConvertHelper.ToDataTable(l);
}
/// <summary>
/// 获取下级站点
/// </summary>
/// <param name="stationID"></param>
/// <returns></returns>
public static DataTable GetStationByID(StationType stationID)
{
var lst = GetCache("S_STATION") as S_STATION[];
var l = lst.Where(s => s.BELONGSTATION == stationID.ToString()).Select(s => new { key = s.STATIONNAME, value = s.STATIONID });
return CSMS2.Infrastructure.Helpers.ConvertHelper.ToDataTable(l);
}
/// <summary>
/// 根据键取值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetValueByKey(string key)
{
var lst = GetCache("S_SETTINGS") as S_SETTINGS[];
return lst.Where(s => s.KEYNAME == key).Select(s => s.CONFIGVALUE).First().ToString();
}
/// <summary>
/// 添加表,缓存用
/// </summary>
public static void AddTable()
{
CommonService.CommonClient common = new CommonService.CommonClient();
hs.Add("S_WORDS", common.GetAllWords());
hs.Add("CY_YONGHUPZ", common.GetAllYHWords());
hs.Add("S_SETTINGS", common.GetAllSettings());
hs.Add("S_STATION", common.GetAllStation());
common.Close();
}
/// <summary>
/// 获取缓存数据
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static object GetCache(string key)
{
if (null == hs[key])
{
hs.Clear();
AddTable();
}
return hs[key];
}
/// <summary>
/// 移除缓存对象
/// </summary>
/// <param name="key">键</param>
public static void RemoveCache(string key)
{
hs.Remove(key);
}
}
}