在任何框架中,缓存都是不可或缺的一部分,本框架亦然。在这个框架中,我们的缓存分为两部分:内存缓存和单次请求缓存。简单说来,就是一个使用微软提供的MemoryCache做扩展,并提供全局唯一实例;另一个使用微软提供的HttpContextBase做扩展,用户每发送一次请求,HttpContextBase都会被关联创建。先来看下接口约束:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:   
   6:  namespace TinyFrame.Framework.Caching
   7:  {
   8:      public interface ICacheManager
   9:      {
  10:          //根据key获取缓存对象
  11:          T Get<T>(string key);
  12:   
  13:          //设置缓存对象
  14:          void Set(string key, object data, int cacheTime);
  15:   
  16:          //查询key是否被缓存
  17:          bool IsSet(string key);
  18:   
  19:          //从缓存移除
  20:          void Remove(string key);
  21:   
  22:          //缓存移除匹配
  23:          void RemoveByPattern(string pattern);
  24:   
  25:          //清空所有缓存
  26:          void Clear();
  27:      }
  28:  }

方法不多,但是包含了缓存的增删查。其中Get泛型方法可以通过Key返回缓存对象;Set方法可以添加缓存;IsSet方法可以检测缓存是否存在;Remove方法可以清除已有的单个缓存;RemoveByPattern可以通过正则匹配清除缓存;Clear方法则清除全部缓存。

首先是MemoryCacheManager的实现:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Runtime.Caching;
   6:  using System.Text.RegularExpressions;
   7:   
   8:  namespace TinyFrame.Framework.Caching
   9:  {
  10:      public class MemoryCacheManager:ICacheManager
  11:      {
  12:          protected ObjectCache Cache
  13:          {
  14:              get { return MemoryCache.Default; }
  15:          }
  16:   
  17:          public T Get<T>(string key)
  18:          {
  19:              return (T)Cache[key];
  20:          }
  21:   
  22:          public void Set(string key, object data, int cacheTime)
  23:          {
  24:              if (data == null)
  25:                  return;
  26:              var policy = new CacheItemPolicy();
  27:              policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime);
  28:              Cache.Add(new CacheItem(key,data),policy);
  29:   
  30:          }
  31:   
  32:          public bool IsSet(string key)
  33:          {
  34:              return Cache.Contains(key);
  35:          }
  36:   
  37:          public void Remove(string key)
  38:          {
  39:              Cache.Remove(key);
  40:          }
  41:   
  42:          public void RemoveByPattern(string pattern)
  43:          {
  44:              var regex = new Regex(pattern, RegexOptions.Singleline
  45:                                              | RegexOptions.Compiled
  46:                                              | RegexOptions.IgnoreCase);
  47:              var keysToRemove = new List<string>();
  48:              foreach (var item in Cache)
  49:                  if (regex.IsMatch(item.Key))
  50:                      keysToRemove.Add(item.Key);
  51:   
  52:              foreach (string key in keysToRemove)
  53:              {
  54:                  Remove(key);
  55:              }
  56:          }
  57:   
  58:          public void Clear()
  59:          {
  60:              foreach (var item in Cache)
  61:              {
  62:                  Remove(item.Key);
  63:              }
  64:          }
  65:      }
  66:  }

然后是PerRequestCacheManager的实现:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Web;
   6:  using System.Collections;
   7:  using System.Text.RegularExpressions;
   8:   
   9:  namespace TinyFrame.Framework.Caching
  10:  {
  11:      public class PerRequestCacheManager : ICacheManager
  12:      {
  13:          public PerRequestCacheManager(HttpContextBase context)
  14:          {
  15:              this.context = context;
  16:          }
  17:   
  18:          private readonly HttpContextBase context;
  19:   
  20:          protected virtual IDictionary GetItems()
  21:          {
  22:              if (context != null)
  23:                  return context.Items;
  24:   
  25:              return null;
  26:          }
  27:   
  28:          public T Get<T>(string key)
  29:          {
  30:              var items = GetItems();
  31:              if (items == null)
  32:                  return default(T);
  33:   
  34:              return (T)items[key];
  35:          }
  36:   
  37:          public void Set(string key, object data, int cacheTime)
  38:          {
  39:              var items = GetItems();
  40:              if (items == null)
  41:                  return;
  42:   
  43:              if (data != null)
  44:              {
  45:                  if (items.Contains(key))
  46:                      items[key] = data;
  47:                  else
  48:                      items.Add(key, data);
  49:              }
  50:          }
  51:   
  52:          public bool IsSet(string key)
  53:          {
  54:              var items = GetItems();
  55:              if (items == null)
  56:                  return false;
  57:   
  58:              return items[key] != null;
  59:          }
  60:   
  61:          public void Remove(string key)
  62:          {
  63:              var items = GetItems();
  64:              if (items == null)
  65:                  return;
  66:   
  67:              items.Remove(key);
  68:          }
  69:   
  70:          public void RemoveByPattern(string pattern)
  71:          {
  72:              var items = GetItems();
  73:              if (items == null)
  74:                  return;
  75:   
  76:              var enumerator = items.GetEnumerator();
  77:              var regex = new Regex(pattern, RegexOptions.Singleline
  78:                                            | RegexOptions.Compiled
  79:                                            | RegexOptions.IgnoreCase);
  80:              var keysToRemove = new List<string>();
  81:              while (enumerator.MoveNext())
  82:              {
  83:                  if (regex.IsMatch(enumerator.Key.ToString()))
  84:                  {
  85:                      keysToRemove.Add(enumerator.Key.ToString());
  86:                  }
  87:              }
  88:   
  89:              foreach (string key in keysToRemove)
  90:              {
  91:                  items.Remove(key);
  92:              }
  93:          }
  94:   
  95:          public void Clear()
  96:          {
  97:              var items = GetItems();
  98:              if (items == null)
  99:                  return;
 100:   
 101:              var enumerator = items.GetEnumerator();
 102:              var keysToRemove = new List<string>();
 103:              while (enumerator.MoveNext())
 104:              {
 105:                  keysToRemove.Add(enumerator.Key.ToString());
 106:              }
 107:   
 108:              foreach (string key in keysToRemove)
 109:              {
 110:                  items.Remove(key);
 111:              }
 112:          }
 113:      }
 114:  }

二者的实现方式差不多。这里我就不做过多的解释了。

如果想使用的话,直接在Autofac容器中注册一下就行了。在这次演示中,我们使用MemoryCacheManager来做缓存容器。

这里我以一个分页为例:

   1:  string BookPaggerKey = "Books-{0}-{1}-{2}-{3}";
   2:          //分页查询
   3:          public IList<Book> GetBooksPagger(int pageCount
   4:                                          , int currentIndex
   5:                                          , out int totalCount
   6:                                          , string propertyName=""
   7:                                          , string propertyValue=""
   8:                                          )
   9:          {
  10:              IQueryable<Book> bookList = null;
  11:              int skipRows = 0;
  12:              if (currentIndex > 0) skipRows = currentIndex * pageCount;
  13:   
  14:              if (!string.IsNullOrEmpty(propertyName))
  15:                  bookList = GetBooksByConstruct(propertyName, propertyValue);
  16:              else
  17:                  bookList = bookRepository.GetMany(m => m.ID >= 0);
  18:              totalCount = bookList.Count();
  19:              
  20:              //return bookList.OrderBy(p => p.ID).Skip(skipRows).Take(pageCount).ToList();
  21:              string key = string.Format(BookPaggerKey, pageCount, currentIndex, propertyName, propertyValue);
  22:   
  23:              return cacheManager.Get(key, () => bookList.OrderBy(p => p.ID).Skip(skipRows).Take(pageCount).ToList());
  24:          }

第1行:定义了一个Cache的Key,用于标识保存ID

第23行:利用get方法检查缓存容器,如果缓存中数据不存在,则将查询数据添加到缓存;否则直接从缓存中拿出数据来。

我们来看看效果:

首先打开页面,我们换换页,目的是让页面被缓存住:

然后我们打开SQL的SQL Server Profile来进行追踪,现在,我们点击页面的刷新按钮,看看测试效果 :

当我们连续刷新页面好几次,但是并未见到有新的分页查询被追踪到,说明我们的数据被缓存住了。

最后我们加个断点调试一下缓存对象,可以找到被缓存的数据:

转载于:https://www.cnblogs.com/scy251147/p/3667541.html

TinyFrame升级之五:全局缓存的设计及实现相关推荐

  1. 【Visual C++】游戏开发笔记三十七 浅墨DirectX提高班之五 顶点缓存的红颜知己:索引缓存的故事

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8304741 作者:毛星云(浅墨 ...

  2. 缓存层设计套路(一)

    一.背景 对于传统的后端业务场景(或者单机应用)中,访问量以及对响应时间的要求均不高,通常只使用DB即可满足要求.这种架构简单,便于快速部署,很多网站发展初期均考虑使用这种架构.但是随着访问量的上升, ...

  3. 10倍,BoostKit鲲鹏全局缓存3大创新技术助力Ceph性能提升

    摘要:本文从四个方面阐述了BoostKit鲲鹏全局缓存技术,该技术针对Ceph开源存储方案存在的痛点,采用三大创新技术,有效的提高了Ceph的性能,最高可以将Ceph性能提升10倍. 本文分享自华为云 ...

  4. Android OTA 升级之五:updater

    2011-03-15 20:14 4164人阅读 评论(7) 收藏 举报 Android OTA 升级之五:updater 作者: 宋立新 Email:zjujoe@yahoo.com 前言 可以说, ...

  5. Camstar开发:缓存的设计与实现(整合Redis实例)

    目录 1引言 2实例描述 3开发分析 4 实例类图 5 代码分析 5.1 RedisHelper 5.2 ReceiveOrderCache 5.3 IReceiveOrder 5.4 AbsRece ...

  6. 商品详情页动态渲染系统:大型网站的多机房4级缓存架构设计

    124_大型电商网站的商品详情页的深入分析 之前,咱们也是说在讲解这个商品详情页系统的架构 缓存架构,高可用服务 商品详情页系统,我们只是抽取了其中一部分来讲解,而且还做了很大程度的简化 主要是为了用 ...

  7. Redis缓存策略设计及常见问题

    Redis缓存设计及常见问题 缓存能够有效地加速应用的读写速度,同时也可以降低后端负载,对日常应用的开发至关重要.下面会介绍缓存使用技巧和设计方案,包含如下内容:缓存的收益和成本分析.缓存更新策略的选 ...

  8. 最全面的缓存架构设计

    一.缓存技术和框架的重要性 互联网的一些高并发,高性能的项目和系统中,缓存技术是起着功不可没的作用.缓存不仅仅是key-value的简单存取,它在具体的业务场景中,还是很复杂的,需要很强的架构设计能力 ...

  9. 缓存架构设计细节二三事

    缓存架构设计细节二三事 原创 2016-03-08 58沈剑 架构师之路 本文主要讨论这么几个问题: (1)"缓存与数据库"需求缘起 (2)"淘汰缓存"还是&q ...

最新文章

  1. Blender三维建模和动画风格化的东方场景视频教程
  2. R语言PCA主成分分析(Principle Component Analysis)与线性回归结合实战
  3. [ CodeForces 865 D ] Buy Low Sell High
  4. SqlConnetction类
  5. C++ vector,STL vector
  6. python交换两个值原理_python 两数交换新写法原理
  7. 机器学习导论--1.机器学习理论基础详解
  8. 微电子学前沿讲座三-国产EDA的困境-刘伟民博士
  9. 浅谈大数据时代之影响力
  10. 微商必看:快速加微信好友的技巧
  11. LiveGBS国标GB/T28181如何配置按需云端录像(播放时候录像)和一直录像
  12. Linux 安装 JDK + Tomcat + Mysql
  13. 期望/概率dp 学习报告
  14. linux平台下苹果打包研究
  15. Android获取系统的硬件信息、系统版本以及如何检测ROM类型
  16. RJ45和RJ48的区别
  17. python 文件操作大总结 对文件的增删改查,备份, 批量修改,创建和删除 文件的备份
  18. 记单词05-od,-hod(路)
  19. 一套效果图适配(Android和IOS)全尺寸和标注规范-(结果)
  20. Illegal unit of measure (pt inserted) 问题

热门文章

  1. jq localStorage
  2. [react] 你知道的react性能优化有哪些方法?
  3. 前端学习(3340):ant design中icon图标的使用
  4. [html] 写一个布局,当页面滚动一定高时,导航始终固定在顶部,反之恢复原位
  5. 前端学习(2211):网络请求模块的选择--axios的配置相关
  6. 前端学习(1867)vue之电商管理系统电商系统之登录退出实现表单的重置
  7. 前端学习(1683):前端系列实战课程之让蛇吃食物变长
  8. 前端学习(833):操作元素小结
  9. Python time strftime()方法
  10. matlab 画箱线图boxplot简单用法