这几天在面试,这个关于Redis缓存的博客一直没空写,今天总算有点时间了。

从很久很久之前,我就一直想学Redis了,反正看到各大招聘网上都要求Redis,不学就太落后了。

一开始我是按微软官网文档那样配置的,然后发现这也太简单了,不止配置简单,连使用都这么简单,简单得有点过分。如下图所示,它是基于IDistributedCache接口注入的

这么简单,怎么玩,我连判断某个key值存不存在都没办法。

当然了。绝对不是这么简单的。更高级的用法如下,要引入Microsoft.Extensions.Caching.StackExchangeRedis包

ConnectionMultiplexer connection = ConnectionMultiplexer.Connect("127.0.0.1:6379");
IDatabase cache = connection.GetDatabase();
cache.HashSet("key", "hashKey", "value");
cache.SetAdd("key2", "value");

那要怎么用在系统里呢,当然直接使用IDatabase也可以,但不够优雅,而且我还想通过配置文件,来决定是否启用Redis,如果不启用的话,就使用MemoryCache。非常好。想法有了。

先定义一个接口ICacheHelper,这是用来注入的接口,我暂时只定义了string类型跟hash类型的缓存方法

public interface ICacheHelper
{
bool Exists(string key); void Set<T>(string key, T value); T Get<T>(string key); void Delete(string key); void Expire(string key, DateTime dateTime);
void Expire(string key, TimeSpan timeSpan); void HashSet(string key, string hashKey, object hashValue);
T HashGet<T>(string key, string hashKey); bool HashExists(string key, string hashKey); void HashDelete(string key, string hashKey);
}

然后用Redis实现这个接口,RedisCacheHelper类

/// <summary>
/// Redis助手
/// </summary>
public class RedisCacheHelper : ICacheHelper
{
public IDatabase _cache; private ConnectionMultiplexer _connection; private readonly string _instance;
public RedisCacheHelper(RedisCacheOptions options, int database = )
{
_connection = ConnectionMultiplexer.Connect(options.Configuration);
_cache = _connection.GetDatabase(database);
_instance = options.InstanceName;
} public bool Exists(string key)
{
return _cache.KeyExists(_instance + key);
} public void Set<T>(string key, T value)
{
_cache.StringSet(_instance + key, CommonHelper.ObjectToJsonString(value));
} public T Get<T>(string key)
{
return CommonHelper.JsonStringToObject<T>(_cache.StringGet(_instance + key));
} public void Delete(string key)
{
_cache.KeyDelete(_instance + key);
} public void Expire(string key, DateTime dateTime)
{
_cache.KeyExpire(_instance + key, dateTime);
}
public void Expire(string key, TimeSpan timeSpan)
{
_cache.KeyExpire(_instance + key, timeSpan);
}
public void HashSet(string key, string hashKey, object hashValue)
{
string value = CommonHelper.ObjectToJsonString(hashValue);
_cache.HashSet(_instance + key, hashKey, value);
} public T HashGet<T>(string key, string hashKey)
{
var value = _cache.HashGet(_instance + key, hashKey);
return CommonHelper.JsonStringToObject<T>(value);
} public object HashGet(string key, string hashKey, Type type)
{
var value = _cache.HashGet(_instance + key, hashKey);
return CommonHelper.JsonStringToObject(value, type);
} public bool HashExists(string key, string hashKey)
{
return _cache.HashExists(_instance + key, hashKey);
} public void HashDelete(string key, string hashKey)
{
_cache.HashDelete(_instance + key, hashKey);
}
}

再用MemoryCache实现接口,MemoryCacheHelper类

/// <summary>
/// 缓存助手
/// </summary>
public class MemoryCacheHelper : ICacheHelper
{
private readonly IMemoryCache _cache;
public MemoryCacheHelper(IMemoryCache cache)
{
_cache = cache;
} public bool Exists(string key)
{
return _cache.TryGetValue(key, out _);
} public T Get<T>(string key)
{
return _cache.Get<T>(key);
} public void Delete(string key)
{
_cache.Remove(key);
} public void Set<T>(string key, T value)
{
_cache.Set(key, value);
}
public void Expire(string key, DateTime dateTime)
{
var value = _cache.Get(key);
_cache.Set(key, value, dateTime);
} public void Expire(string key, TimeSpan timeSpan)
{
var value = _cache.Get(key);
_cache.Set(key, value, timeSpan);
}
public void HashSet(string key, string hashKey, object hashValue)
{
var hash = _cache.Get<Dictionary<string, object>>(key);
if (hash.ContainsKey(hashKey))
{
hash[key] = hashValue;
}
else
{
hash.Add(hashKey, hashValue);
}
_cache.Set<Dictionary<string, object>>(key, hash);
} public T HashGet<T>(string key, string hashKey)
{
var hash = _cache.Get<Dictionary<string, object>>(key);
if (hash.ContainsKey(hashKey))
{
return (T)hash[hashKey];
}
else
{
return default(T);
}
} public bool HashExists(string key, string hashKey)
{
var hash = _cache.Get<Dictionary<string, object>>(key);
return hash.ContainsKey(hashKey);
} public void HashDelete(string key, string hashKey)
{
var hash = _cache.Get<Dictionary<string, object>>(key);
if (hash.ContainsKey(hashKey))
{
hash.Remove(hashKey);
}
}
}

实现类都有了,那现在就来实现根据配置值来决定是否使用Redis还是MemoryCache,先在appsettings.json里添加这个配置值,当Enable为false时,就不启用Redis,使用MemoryCache,Connection是Redis的连接字符串,InstanceName是缓存的前缀,Database是使用哪个数据库

"Redis": {
"Enable": true,
"Connection": "127.0.0.1:6379",
"InstanceName": "LessSharp:",
"Database":
}

再定义一个选项类 RedisOption

public class RedisOption
{
public bool Enable { get; set; }
public string Connection { get; set; }
public string InstanceName { get; set; }
public int Database { get; set; }
}

然后在Startup.cs类里的ConfigureServices里根据配置值进行注入

var RedisConfiguration = Configuration.GetSection("Redis");
services.Configure<RedisOption>(RedisConfiguration);
RedisOption redisOption = RedisConfiguration.Get<RedisOption>();
if (redisOption != null && redisOption.Enable)
{
var options = new RedisCacheOptions
{
InstanceName = redisOption.InstanceName,
Configuration = redisOption.Connection
};
var redis = new RedisCacheHelper(options, redisOption.Database);
services.AddSingleton(redis);
services.AddSingleton<ICacheHelper>(redis);
}
else
{
services.AddMemoryCache();
services.AddScoped<ICacheHelper, MemoryCacheHelper>();
}

OK,测试后完美

最新文章

  1. API -- java.lang.Integer
  2. Hyper-v之利用差异磁盘快速创建多个虚拟机
  3. AngularJs bower install 卡主不动解决办法
  4. HDU 4652 Dice(期望)
  5. BITED-Windows8应用开发学习札记之二:Win8应用常用视图设计
  6. 通过源码看android系列之AsyncTask
  7. JavaScript 数据类型转换(显式与隐式)
  8. jquery中的uploadfile关于图片上上传的插件的应用
  9. Windows下一个AndroidStudio 正在使用Git(AndroidStudio工程GitHub关联)
  10. bzoj2500幸福的道路 树形dp+单调队列
  11. Hadoop问题:DataNode进程不见了
  12. Kubernetes 笔记 02 demo 初体验
  13. Oracle导出数据EXP00106错误
  14. 用python批量生成简单的xml文档
  15. Flink - watermark生成
  16. Mysql初级第三天(wangyun)
  17. Go语言高级特性总结——Struct、Map与JSON之间的转化
  18. STM32F4, USB HS with ULPI and Suspend/Wakeup
  19. Echart 仪表盘和柱形图
  20. C#学习笔记(22)——C#创建文本文件txt并追加写入数据

热门文章

  1. Spring Boot 2.3.0正式发布:优雅停机、配置文件位置通配符新特性一览
  2. bzoj4512[Usaco2016 Jan] Build Gates
  3. 问题:IE11下window.history.go(-1)返回404
  4. Java图片验证码生成工具
  5. CentOS 无法加载 ntfs文件系统类型解决办法
  6. 【Docker】Redis 安装使用教程
  7. vue使用select间相互绑定
  8. 原来python还可以这样处理文件
  9. RN开发杂记
  10. .Net Core Controller