C# 基础数据缓存

最近做一个C#项目,刚做完基础数据,现把缓存机制给大家分享一下:

做过基础数据的同学应该都知道,每次涉及到查询数据时都会去数据库把配置好的基础数据查询出来,这样每次在操作是会很慢。那么我们每次点开一个新页面都会去数据库查询一下基础数据,这样会频繁的连接数据库,用户多了之后肯定就会特别慢。因为数据一旦配好之后就会很少去改动它,所以我们可以做一个缓存把每次查询出来的基础数据缓存起来,这样就可以提高查询效率。好了,废话不多说了,上代码。

我声明一下我用的是Dictionary数据字典,您也可以使用Cache等等别的技术,实现机制都一样。

我使用了一个接口,一个抽象类,一个工厂类,一个普通类。

首先我们得定义设置缓存,获取缓存,删除缓存的方法,还要定义缓存的大小,太大了就会不好控制,消耗内存。在接口中定义方法,然后用抽象类继承接口实现方法,因为缓存是一直保存在整个网站运行期间,所以不能实例化它,我们得用abstract类,用工厂模式实现调用。 需要注意一点就是我们可以定义Dictionary里面的类型为泛型类而不用object类型,这样在使用的时候就不用装箱,拆箱。

以下是接口ICache代码:

/// <summary> 
/// 设置缓存 
/// </summary> 
/// <param name="key"></param> 
/// <param name="value"></param> 
void SetCache(TKey key, TValue value);

/// <summary> 
/// 获取缓存 
/// </summary> 
/// <param name="key"></param> 
/// <returns></returns> 
TValue GetCache(TKey key);

/// <summary> 
/// 清空指定缓存 
/// </summary> 
void Clear(TKey key);

/// <summary> 
/// 清空当前登录用户的缓存 
/// </summary> 
/// <param name="key"></param> 
void ClearAll();

/// <summary> 
/// 定义缓存Key 
/// </summary> 
/// <param name="key"></param> 
/// <returns></returns> 
TKey JoinKey(TKey key);

/// <summary> 
/// 缓存大小 
/// </summary> 
int CacheSize { get; set; }

接着,我们用一个抽象类(AbstractCache)继承接口,这里面的大部分都是虚方法,因为我们在使用的时候考虑到还有别的缓存,所以可以在继承类里面重写这些方法。

public AbstractCache(string type) 

this._type = type; 
if (AbstractCache<TKey, TValue>._cacheList == null) 

AbstractCache<TKey, TValue>._cacheList = new Dictionary<string, Dictionary<TKey, TValue>>(); 

if (!AbstractCache<TKey, TValue>._cacheList.ContainsKey(_type)) 

AbstractCache<TKey, TValue>._cacheList.Add(this._type, new Dictionary<TKey, TValue>()); 


private static Dictionary<string, Dictionary<TKey, TValue>> _cacheList; 
private string _type; 
private int _cacheSize = 100;

public virtual void SetCache(TKey key, TValue value) 

Dictionary<TKey, TValue> dic = this.getTypeCache(); 
lock (AbstractCache<TKey, TValue>._cacheList) 

TKey fullKey = this.JoinKey(key); 
if (!dic.ContainsKey(fullKey)) 

if (dic.Count >= this._cacheSize) 

if (dic.Keys.Count > 0) 

TKey tmpKey = default(TKey); 
foreach (TKey k in dic.Keys) 

tmpKey = k; 
break; 

dic.Remove(tmpKey); 


if (value != null) 

dic.Add(fullKey, value); 

else 

dic.Add(fullKey, default(TValue)); 


else 

if (value != null) 

dic[fullKey] = value; 

else 

dic[fullKey] = default(TValue); 



}

public virtual TValue GetCache(TKey key) 

Dictionary<TKey, TValue> dic = this.getTypeCache(); 
TKey fullKey = this.JoinKey(key); 
if (dic.ContainsKey(fullKey)) 

return dic[fullKey]; 

return default(TValue); 
}

public virtual void Clear(TKey key) 

Dictionary<TKey, TValue> dic = this.getTypeCache(); 
lock (AbstractCache<TKey, TValue>._cacheList) 

TKey fullKey = this.JoinKey(key); 
if (dic.ContainsKey(fullKey)) 

dic.Remove(fullKey); 



public virtual void ClearAll() 

throw new NotImplementedException(); 
}

public abstract TKey JoinKey(TKey key);

public int CacheSize 

get 

return _cacheSize; 

set 

_cacheSize = value; 

}

/// <summary> 
/// 获取当前类型的缓存数据 
/// </summary> 
/// <returns></returns> 
protected Dictionary<TKey, TValue> getTypeCache() 

Dictionary<TKey, TValue> dic = AbstractCache<TKey, TValue>._cacheList[this._type]; 
if (dic == null) 

throw new Exception("不正确的初始化方式"); 

return dic; 
}

接下来我们需要顶一个DataAuthCache类来继承抽象类重写一些自己需要的方法,

public DataAuthCache() 
: base("DataAuthCache")  //这个参数是区分缓存那一部分类容的 


private static object _lockObj = new object(); 
public override string JoinKey(string entityName) 

return Entity.Session.Manage.Current.AuthContext.OrgID + "_" + Entity.Session.Manage.Current.AuthContext.UserID + "_" + entityName; 

public override void ClearAll() 

long orgKey = Entity.Session.Manage.Current.AuthContext.OrgID; 
long userKey = Entity.Session.Manage.Current.AuthContext.UserID; 
lock (_lockObj) 

Dictionary<string, string> dic = this.getTypeCache(); 
string containKey = orgKey + "_" + userKey; 
List<string> keys = new List<string>(); 
//Dictionary里面Keys不能用索引直接访问 
foreach (string key in dic.Keys) 

keys.Add(key);


if (keys.Count > 0) 

foreach (string key in keys) 

if (key.IndexOf(containKey) > 0) 

dic.Remove(key); 




}

然后,我们可以定义一个工厂类(AbstractCacheFactory)来实现外部的调用

private static ICache<string, string> _dataAuthCache = null; 
public static AbstractCache<string, string> GetDataAuthCache() 

if (_dataAuthCache == null) 

_dataAuthCache = new DataAuthCache(); 

return (AbstractCache<string, string>)_dataAuthCache; 
}

好了,到这,我们就完成缓存了,很简单吧!

AbstractCache<string, string> dac =AbstractCacheFactory.GetDataAuthCache(); 
string cacheHql = dac.GetCache(tpl.EntityName);

cacheHql就是我们缓存的数据查询片段,好了,就分享到这儿了。欢迎大家提出宝贵意见,和分享搞好的方法。

时间: 2024-11-10 15:30:01

C# 基础数据缓存的相关文章

jQuery源代码学习之六——jQuery数据缓存Data

一.jQuery数据缓存基本原理 jQuery数据缓存就两个全局Data对象,data_user以及data_priv; 这两个对象分别用于缓存用户自定义数据和内部数据: 以data_user为例,所有用户自定义数据都被保存在这个对象的cache属性下,cache在此姑且称之为自定义数据缓存: 自定义数据缓存和DOM元素/javascript对象通过id建立关联,id的查找通过DOM元素/javascript元素下挂载的expando属性获得 话不多说,直接上代码.相关思路在代码注释中都有讲解

Spring整合Redis做数据缓存(Windows环境)

当我们一个项目的数据量很大的时候,就需要做一些缓存机制来减轻数据库的压力,提升应用程序的性能,对于java项目来说,最常用的缓存组件有Redis.Ehcache和Memcached. Ehcache是用java开发的缓存组件,和java结合良好,直接在jvm虚拟机中运行,不需要额外安装什么东西,效率也很高:但是由于和java结合的太紧密了,导致缓存共享麻烦,分布式集群应用不方便,所以比较适合单个部署的应用. Redis需要额外单独安装,是通过socket访问到缓存服务,效率比Ehcache低,但

jQuery.data的是jQuery的数据缓存系统

jQuery.Data源码 jQuery.data的是jQuery的数据缓存系统.它的主要作用就是为普通对象或者DOM元素添加数据. 1 内部存储原理 这个原理很简单,原本要添加在DOM元素本身的数据,现在被集中的存储在cache集合中.它们之间靠一个从1开始的数字键来联系着.这样DOM元素就不会像以前那么笨重了,更不会出现以前那种循环引用而引起的内存泄漏.现在DOM只需要保存好这个数字键值即可.这个属性值被保存在DOM元素的一个属性里,该属性名是由jQuery.expando生成的. 2 Da

用户中心接口对外数据缓存化的实践参考

最近在看通用权限管理系统提供用户中心接口,发现有不少变化,通过与吉日嘎拉大牛的沟通,逐渐了解了用户中心接口前后的变化,现将我的理解分享给大家: 用户中心对外提供了基础信息.权限的接口,刚开始的部署方式采用了如下图的方式,由于客户端及应用服务器的网络环境,接口服务器配置了多个电信运营商的网络链接: 最初在用户量不大的时候,调用接口时是直接访问数据库获取数据向应用服务器输出,随着客户端访问量的增大,用户中心库的压力也逐渐增大,为了保证接口的稳定性,减轻数据库压力,进行了缓存化改造,主要使用了Redi

DrySister看妹子应用(第一版)——4.添加数据缓存(加入SQLite)

DrySister看妹子应用(第一版)--4.添加数据缓存(加入SQLite) 标签(空格分隔): DrySister 1.一些BB ???上节我们为DrySister编写了一个异步图片加载缓存框架--SisterLoader(妹子加载器) 成功的从网络加载的图片缓存到了磁盘和内存中,当我们断开网络后,仍然能够查看这些图片, 但是,细心的你可能发现了一个很尴尬的地方,我们在有网的情况下进入APP,获取到图片相关 的信息,比如URL,如果退出了,断网,然后进来,图片就加载不出来了,图片已经缓存了,

Spring Boot使用redis实现数据缓存

基于Spring Boot 1.5.2.RELEASE版本,一方面验证与Redis的集成方法,另外了解使用方法. 集成方法 配置依赖 修改pom.xml,增加如下内容. <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 配置Redis

(转)Memcache,Redis,MongoDB(数据缓存系统)方案对比与分析

Memcache,Redis,MongoDB(数据缓存系统)方案对比与分析 数据库表数据量极大(千万条),要求让服务器更加快速地响应用户的需求. 二.解决方案: 1.通过高速服务器Cache缓存数据库数据 2.内存数据库 (这里仅从数据缓存方面考虑,当然,后期可以采用Hadoop+HBase+Hive等分布式存储分析平台) 三.主流解Cache和数据库对比: 上述技术基本上代表了当今在数据存储方面所有的实现方案,其中主要涉及到了普通关系型数据库(MySQL/PostgreSQL),NoSQL数据

Memcache,Redis,MongoDB(数据缓存系统)方案对比与分析

mongodb和memcached不是一个范畴内的东西.mongodb是文档型的非关系型数据库,其优势在于查询功能比较强大,能存储海量数据.mongodb和memcached不存在谁替换谁的问题. 和memcached更为接近的是redis.它们都是内存型数据库,数据保存在内存中,通过tcp直接存取,优势是速度快,并发高,缺点是数据类型有限,查询功能不强,一般用作缓存.在我们团队的项目中,一开始用的是memcached,后来用redis替代. 相比memcached: 1.redis具有持久化机

FIFO数据缓存器

FIFO数据缓存器: FIFO (First Input First Output) 一种先进先出的数据缓存器,先进入的数据先从FIFO缓存器中读出,与RAM相比没有外部读写地址线,使用比较简单,但只能顺序写入数据,顺序的读出数据,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址. FIFO数据缓存器的作用: FIFO一般用于不同时钟域之间的数据传输,比如FIFO的一端是AD数据采集,另一端为PCI总线,那么在两个不同的时钟域间就可以采用FIFO来作为数据缓冲.另外对于不同宽度的数据