以前经常看博客园,来到园里也有一年了。看过了无数篇大神的文章。觉得对知识的了解是一种增长。我认识到写东西也是一种积累。所有就常识着在这里记录一点东西。初次写写的不好还望多多关照。请大牛绕路,毕竟新人一枚。还在摸索阶段!!! ~~~~
接触缓存也有一段时间了,以免忘记所以写在这里就当作记录日记吧。不对的还望指点。
缓存的基本分类:
- 简单数据的缓存
- 数据缓存依赖
- 数据库缓存依赖
- 分布式缓存
缓存的简单介绍:
缓存主要解决的问题是:性能,稳定性和可用性。
缓存的生存期一般分为:
永久状态Permanent State——应用程序使用的永久数据;
进程状态Process State——只在进程周期内有效;
会话状态Session State——和特定的用户会话有关;
消息状态Message State——处理某个消息的时间内有效;
缓存基本存放原则:
缓存数据只是一份主数据的拷贝,它可能在内存中或以不同的表现形式保存在硬盘上,也就是说,离这句的使用者越近越好。所以,除了考虑要缓存哪些数据以外,数据缓存在哪里也是一个主要的考量点。这个问题分为以下两个范围:
存储类型Storage Type——数据可用的物理存储位置;
层间的架构元素(Layered architecture elements)——数据可用的逻辑存储位置。
在c#语言中缓存的命名空间为:
System.Web.Caching
缓存命名空间中的类及其说明
类名 |
说明 |
Cache |
对缓存对象的编辑类,其操作包括缓存的增、删、改 |
CacheDependency |
基本缓存对象的依赖,当基本对象发生变化时,更新缓存内容 |
SqlCacheDependency |
数据库缓存对象的依赖,当数据库中的数据变化时,更新缓存内容 |
方法介绍
名称 |
说明 |
Add |
添加数据 |
Insert |
插入数据,也可用作修改已存在的数据 |
Remove |
删除数据 |
Get |
获取项,类型为object |
GetType |
获取cache对象中的数据项类型 |
GetEnumerator |
循环访问cache的缓存数据项 |
代码示例:
ArrayList myarray = new ArrayList(); //创建数组数据
myarray.Add("1.学习园地");
myarray.Add("2.交流论坛");
myarray.Add("3.帮助");
//将数组添加到缓存中——使用Add方法
System.Web.HttpContext.Current.Cache.Add("Category", myarray, null, DateTime.Now.AddSeconds(60), TimeSpan.Zero, CacheItemPriority.Normal, null);
myarray[1] = "2.交流园地"; //修改数组数据
System.Web.HttpContext.Current.Cache.Insert("Category", myarray); //使用Insert方法修改缓存数据
string tmpStr = "这是一个临时数据";
System.Web.HttpContext.Current.Cache["tmpdata"] = tmpStr;
//使用Get方法获取缓存数据
Response.Write(Cache.Get("tmpdata").ToString()+"<br/>");/
Cache["tmpdata"] = "这是一个临时字符串"; //重新为缓存赋值的技巧
Response.Write(Cache.Get("tmpdata").ToString() + "<br/>");
//使用GetType方法判断缓存数据的类型
if (Cache["Category"].GetType().Name == "ArrayList")
Response.Write("类型是数组");
//使用GetEnumerator方法遍历缓存中的数据
IDictionaryEnumerator mycache = Cache.GetEnumerator();
while (mycache.MoveNext())
Response.Write(mycache.Value + "<br/>");
Cache.Remove("tmpdata");//使用Remove方法移除缓存的临时数据
}
输出缓存
[OutputCache(Duration=10)]
解释:把他放到页面方法上她会对此页面进行缓存,duration设置的是缓存的寿命时间秒,在缓存寿命没到期限,刷新或者加载此方法不会进行重新加载,之后读取缓存的数据。注意此处的页面缓存不与数据缓存冲突。
参数:
时间参数是必须设置的。还有下面四个可以根据情况选择设置:
VaryByContentEncoding(一般设置为Accept-Encoding里面可能的Encoding名称)
VaryByCustom(定制,暂不研究)
VaryByHeader(根据header决定是否读取缓存)
VaryByParam(根据参数不同不启用缓存)
除了以上四个基本属性还有一个重要的属性,他能影响缓存的位置Location属性,一下是这个属性的几个选项:
成员名称 |
说明 |
Any |
输出缓存可位于产生请求的浏览器客户端、参与请求的代理服务器(或任何其他服务器)或处理请求的服务器上。(这是默认值) |
Client |
输出缓存位于产生请求的浏览器客户端上。 |
Downstream |
输出缓存可存储在任何 HTTP 1.1 可缓存设备中,源服务器除外。这包括代理服务器和发出请求的客户端。 |
Server |
输出缓存位于处理请求的 Web 服务器上。 |
None |
对于请求的页,禁用输出缓存。 |
ServerAndClient |
输出缓存只能存储在源服务器或发出请求的客户端中。代理服务器不能缓存响应。 |
依赖缓存
文件依赖
CacheDependency dp = new CacheDependency(Server.MapPath("/Data/123.txt"));//建立缓存依赖项dp
string str = System.IO.File.ReadAllText(Server.MapPath("/Data/111.txt"));
CacheHelper.Set("text2",str,dp);
注意依赖缓存的原理就是根据依赖项的修改状态,加入修改就对此缓存做删除操作,而且即时你设置依赖缓存如果你在设置依赖缓存之后再一次对缓存的主键设置键值(发生改变),此时值也会改变,与数据缓存没有什么差距。以来缓存仅仅是多了一个文件监控效果。
小提示:
依赖缓存可以同时依赖多个依赖项。
数据库依赖
- 打开项目配置文件
<connectionStrings>
<add name="config " connectionString="data source=localhost;initial catalog=数据库名;uid=sa;password=1234;" />
</connectionStrings>
<system.web>
<caching>
<sqlCacheDependency enabled="true" pollTime="2000">
<databases>
<add name="Test" connectionStringName="Am_WeixinWeb"/>
</databases>
</sqlCacheDependency>
</caching>
- 启动数据库缓存依赖
在C盘中,搜索到工具aspnet_regsql.exe
在命令中 cd:运行到此工具的文件下,键入下面命令
aspnet_regsql -C "data source=;initial catalog=codematic;user id=sa;password=" -ed -et -t "T_table"
3.使用缓存依赖项
//sql缓存依赖
DataSet ds = new DataSet();
if (cache.Get("key") == null)
{
string conStr = DoXml.ReadWebConfigConnectionStrings("Am_WeixinWeb");
SqlConnection conn = new SqlConnection(conStr);
string sql = "select top(1) recContent from Am_recProScheme";
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
sda.Fill(ds, "tb1");
SqlCacheDependency dep = new SqlCacheDependency("Test", "Am_recProScheme"); //Test对应配置项的缓存配置key ,后面是数据库表名
cache.Insert("key", ds.Tables["tb1"].Rows[0]["recContent"].ToString(), dep);
}
Response.Write(cache.Get("key"));
原理:
数据库依赖会在你配置完之后在数据库生成一个触发器并对应一个表文件(A),实际的监控就是生成的触发器监控数据库原表(B)即A监控B,然后代码通过配置文件监控A里面的某个字段值,当这个值变化时,不管B是否真的变化,程序也会认为数据库发生了变化,从而清空缓存数据。
使用缓存配置文件:
除了在页面上设置还可以通过web.config进行设置。通过OutputCache特性的CacheProfile属性来引用该配置文件。
配置节点:
<system.web>
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="MyProfile" duration="60" varyByParam="*" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
</system.web>
使用缓存API
缓存API的主要作用是用来对缓存更加细腻化,因为OutputCache是对Action的缓存,不同的Action之间是不能共享数据的,假如某些数据,我们是在不同的Action之间共享的,那么,简单地采用OutputCache来做,就会导致对同一份数据,缓存多次的问题。缓存API就是针对此问题的一种缓存延伸。
关于如何通过API的方式添加或者使用缓存,请参考:
http://msdn.microsoft.com/zh-cn/library/18c1wd61%28v=VS.80%29.aspx
附加一个1.0到4.0的bug:
使用缓存 后请求缓存页面多次报200-304-200-304问题,在缓存方法添加以下代码即可
Response.Cache.SetOmitVaryStar(true);