.NET Core Redis 帮助类五大类型实现
一、使用默认 IOC 注入
1. 方式一 系统 IOC 注入:Startup 类 ConfigureServices 方法中添加以下代码
services.AddTransient(); services.AddTransient (); services.AddTransient (); services.AddTransient (); services.AddTransient ();
2. 方式二 Autofac 注入 Startup 类 ConfigureContainer 方法中添加以下代码
////// Autofac /// /// public void ConfigureContainer(ContainerBuilder builder) { builder.RegisterType(); builder.RegisterType (); builder.RegisterType (); builder.RegisterType (); builder.RegisterType (); }
二、Redis 配置类
////// redis配置文件信息 /// 也可以放到配置文件去 /// public sealed class RedisConfigInfo { ////// 可写的Redis链接地址 /// format:ip1,ip2 /// 默认6379端口 /// /// 如果有密码按下面格式填写 /// password@ip:port /// public string WriteServerList = "124.223.85.193:6379"; ////// 可读的Redis链接地址 /// format:ip1,ip2 /// public string ReadServerList = "124.223.85.193:6379"; ////// 最大写链接数 /// public int MaxWritePoolSize = 60; ////// 最大读链接数 /// public int MaxReadPoolSize = 60; ////// 本地缓存到期时间,单位:秒 /// public int LocalCacheTime = 180; ////// 自动重启 /// public bool AutoStart = true; ////// 是否记录日志,该设置仅用于排查redis运行时出现的问题, /// 如redis工作正常,请关闭该项 /// public bool RecordeLog = false; }
三、Redis 管理中心 创建 Redis 链接
////// Redis管理中心 创建Redis链接 /// public class RedisManager { ////// redis配置文件信息 /// private static RedisConfigInfo RedisConfigInfo = new RedisConfigInfo(); ////// Redis客户端池化管理 /// private static PooledRedisClientManager prcManager; ////// 静态构造方法,初始化链接池管理对象 /// static RedisManager() { CreateManager(); } ////// 创建链接池管理对象 /// private static void CreateManager() { string[] WriteServerConStr = RedisConfigInfo.WriteServerList.Split(','); string[] ReadServerConStr = RedisConfigInfo.ReadServerList.Split(','); prcManager = new PooledRedisClientManager(ReadServerConStr, WriteServerConStr, new RedisClientManagerConfig { MaxWritePoolSize = RedisConfigInfo.MaxWritePoolSize, MaxReadPoolSize = RedisConfigInfo.MaxReadPoolSize, AutoStart = RedisConfigInfo.AutoStart, }); } ////// 客户端缓存操作对象 /// public static IRedisClient GetClient() { return prcManager.GetClient(); } }
四、RedisBase 类,是 redis 操作的基类,继承自 IDisposable 接口,主要用于释放内存
////// RedisBase类,是redis操作的基类,继承自IDisposable接口,主要用于释放内存 /// public abstract class RedisBase : IDisposable { public IRedisClient IClient { get; private set; } ////// 构造时完成链接的打开 /// public RedisBase() { IClient = RedisManager.GetClient(); } private bool _disposed = false; protected virtual void Dispose(bool disposing) { if (!this._disposed) { if (disposing) { IClient.Dispose(); IClient = null; } } this._disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } public void Transcation() { using IRedisTransaction irt = IClient.CreateTransaction(); try { irt.QueueCommand(r => r.Set("key", 20)); irt.QueueCommand(r => r.Increment("key", 1)); irt.Commit(); // 提交事务 } catch (Exception) { irt.Rollback(); throw; } } ////// 清除全部数据 请小心 /// public virtual void FlushAll() { IClient.FlushAll(); } ////// 保存数据DB文件到硬盘 /// public void Save() { IClient.Save();//阻塞式save } ////// 异步保存数据DB文件到硬盘 /// public void SaveAsync() { IClient.SaveAsync();//异步save } }
五、Redis 各类型实现
1.Hash
////// Hash:类似dictionary,通过索引快速定位到指定元素的,耗时均等,跟string的区别在于不用反序列化,直接修改某个字段 /// string的话要么是 001:序列化整个实体 /// 要么是 001_name: 001_pwd: 多个key-value /// Hash的话,一个hashid-{key:value;key:value;key:value;} /// 可以一次性查找实体,也可以单个,还可以单个修改 /// public class RedisHashService : RedisBase { #region 添加 ////// 向hashid集合中添加key/value /// public bool SetEntryInHash(string hashid, string key, string value) { return base.IClient.SetEntryInHash(hashid, key, value); } public void SetRangeInHash(string hashid, IEnumerable> value) { base.IClient.SetRangeInHash(hashid, value); } /// /// 如果hashid集合中存在key/value则不添加返回false, /// 如果不存在在添加key/value,返回true /// public bool SetEntryInHashIfNotExists(string hashid, string key, string value) { return base.IClient.SetEntryInHashIfNotExists(hashid, key, value); } ////// 存储对象T t到hash集合中 /// 需要包含Id,然后用Id获取 /// public void StoreAsHash(T t) { base.IClient.StoreAsHash (t); } #endregion #region 获取 /// /// 获取对象T中ID为id的数据。 /// public T GetFromHash(object id) { return base.IClient.GetFromHash (id); } /// /// 获取所有hashid数据集的key/value数据集合 /// public DictionaryGetAllEntriesFromHash(string hashid) { return base.IClient.GetAllEntriesFromHash(hashid); } /// /// 获取hashid数据集中的数据总数 /// public long GetHashCount(string hashid) { return base.IClient.GetHashCount(hashid); } ////// 获取hashid数据集中所有key的集合 /// public ListGetHashKeys(string hashid) { return base.IClient.GetHashKeys(hashid); } /// /// 获取hashid数据集中的所有value集合 /// public ListGetHashValues(string hashid) { return base.IClient.GetHashValues(hashid); } /// /// 获取hashid数据集中,key的value数据 /// public string GetValueFromHash(string hashid, string key) { return base.IClient.GetValueFromHash(hashid, key); } ////// 获取hashid数据集中,多个keys的value集合 /// public ListGetValuesFromHash(string hashid, string[] keys) { return base.IClient.GetValuesFromHash(hashid, keys); } #endregion #region 删除 /// /// 删除hashid数据集中的key数据 /// public bool RemoveEntryFromHash(string hashid, string key) { return base.IClient.RemoveEntryFromHash(hashid, key); } public bool RemoveEntry(string hashid) { return IClient.Remove(hashid); } #endregion #region 其它 ////// 判断hashid数据集中是否存在key的数据 /// public bool HashContainsEntry(string hashid, string key) { return base.IClient.HashContainsEntry(hashid, key); } ////// 给hashid数据集key的value加countby,返回相加后的数据 /// public double IncrementValueInHash(string hashid, string key, double countBy) { return base.IClient.IncrementValueInHash(hashid, key, countBy); } #endregion }
2.String
////// key-value 键值对:value可以是序列化的数据 /// public class RedisStringService : RedisBase { #region 赋值 ////// 设置key的value /// public bool Set(string key, T value) { //iClient.Db =2; return base.IClient.Set (key, value); } /// /// 设置key的value并设置过期时间 /// public bool Set(string key, T value, DateTime dt) { //iClient.Db = 2; return base.IClient.Set (key, value, dt); } /// /// 设置key的value并设置过期时间 /// public bool Set(string key, T value, TimeSpan sp) { //iClient.Db = 2; return base.IClient.Set (key, value, sp); } /// /// 设置多个key/value 可以一次保存多个key value ---多个key value 不是分多次,是一个独立的命令; /// public void Set(Dictionarydic) { //iClient.Db = 2; base.IClient.SetAll(dic); } #endregion #region 追加 /// /// 在原有key的value值之后追加value,没有就新增一项 /// public long Append(string key, string value) { return base.IClient.AppendToValue(key, value); } #endregion #region 获取值 ////// 获取key的value值 /// public string Get(string key) { return base.IClient.GetValue(key); } ////// 获取多个key的value值 /// public ListGet(List keys) { return base.IClient.GetValues(keys); } /// /// 获取多个key的value值 /// public ListGet (List keys) { return base.IClient.GetValues (keys); } public T Get (string key) { return base.IClient.Get (key); } #endregion #region 获取旧值赋上新值 /// /// 获取旧值赋上新值 /// public string GetAndSetValue(string key, string value) { return base.IClient.GetAndSetValue(key, value); } #endregion #region 辅助方法 ////// 获取值的长度 /// public long GetLength(string key) { return base.IClient.GetStringCount(key); } ////// 自增1,返回自增后的值 保存的是10 调用后,+1 返回11 /// public long Incr(string key) { return base.IClient.IncrementValue(key); } ////// 自增count,返回自增后的值 自定义自增的步长值 /// public long IncrBy(string key, int count) { return base.IClient.IncrementValueBy(key, count); } ////// 自减1,返回自减后的值,Redis操作是单线程操作;不会出现超卖的情况 /// public long Decr(string key) { return base.IClient.DecrementValue(key); } ////// 自减count ,返回自减后的值 /// /// /// ///public long DecrBy(string key, int count) { return base.IClient.DecrementValueBy(key, count); } /// /// 设置滑动过期时间 /// /// /// ///public bool ExpireEntryIn(string key, TimeSpan timeSpan) { return IClient.ExpireEntryIn(key, timeSpan); } #endregion }
3.List
////// Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销, /// Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。 /// public class RedisListService : RedisBase { #region 赋值 ////// 从左侧向list中添加值 /// public void LPush(string key, string value) { base.IClient.PushItemToList(key, value); } ////// 从左侧向list中添加值,并设置过期时间 /// public void LPush(string key, string value, DateTime dt) { base.IClient.PushItemToList(key, value); base.IClient.ExpireEntryAt(key, dt); } ////// 从左侧向list中添加值,设置过期时间 /// public void LPush(string key, string value, TimeSpan sp) { base.IClient.PushItemToList(key, value); base.IClient.ExpireEntryIn(key, sp); } ////// 从右侧向list中添加值 /// public void RPush(string key, string value) { base.IClient.PrependItemToList(key, value); } ////// 从右侧向list中添加值,并设置过期时间 /// public void RPush(string key, string value, DateTime dt) { base.IClient.PrependItemToList(key, value); base.IClient.ExpireEntryAt(key, dt); } ////// 从右侧向list中添加值,并设置过期时间 /// public void RPush(string key, string value, TimeSpan sp) { base.IClient.PrependItemToList(key, value); base.IClient.ExpireEntryIn(key, sp); } ////// 添加key/value /// public void Add(string key, string value) { base.IClient.AddItemToList(key, value); } ////// 添加key/value ,并设置过期时间 /// public void Add(string key, string value, DateTime dt) { base.IClient.AddItemToList(key, value); base.IClient.ExpireEntryAt(key, dt); } ////// 添加key/value。并添加过期时间 /// public void Add(string key, string value, TimeSpan sp) { base.IClient.AddItemToList(key, value); base.IClient.ExpireEntryIn(key, sp); } ////// 为key添加多个值 /// public void Add(string key, Listvalues) { base.IClient.AddRangeToList(key, values); } /// /// 为key添加多个值,并设置过期时间 /// public void Add(string key, Listvalues, DateTime dt) { base.IClient.AddRangeToList(key, values); base.IClient.ExpireEntryAt(key, dt); } /// /// 为key添加多个值,并设置过期时间 /// public void Add(string key, Listvalues, TimeSpan sp) { base.IClient.AddRangeToList(key, values); base.IClient.ExpireEntryIn(key, sp); } #endregion #region 获取值 /// /// 获取list中key包含的数据数量 /// public long Count(string key) { return base.IClient.GetListCount(key); } ////// 获取key包含的所有数据集合 /// public ListGet(string key) { return base.IClient.GetAllItemsFromList(key); } /// /// 获取key中下标为star到end的值集合 /// public ListGet(string key, int star, int end) { return base.IClient.GetRangeFromList(key, star, end); } #endregion #region 阻塞命令 /// /// 阻塞命令:从list为key的尾部移除一个值,并返回移除的值,阻塞时间为sp /// public string BlockingPopItemFromList(string key, TimeSpan? sp) { return base.IClient.BlockingPopItemFromList(key, sp); } ////// 阻塞命令:从多个list中尾部移除一个值,并返回移除的值&key,阻塞时间为sp /// public ItemRef BlockingPopItemFromLists(string[] keys, TimeSpan? sp) { return base.IClient.BlockingPopItemFromLists(keys, sp); } ////// 阻塞命令:从list中keys的尾部移除一个值,并返回移除的值,阻塞时间为sp /// public string BlockingDequeueItemFromList(string key, TimeSpan? sp) { return base.IClient.BlockingDequeueItemFromList(key, sp); } ////// 阻塞命令:从多个list中尾部移除一个值,并返回移除的值&key,阻塞时间为sp /// public ItemRef BlockingDequeueItemFromLists(string[] keys, TimeSpan? sp) { return base.IClient.BlockingDequeueItemFromLists(keys, sp); } ////// 阻塞命令:从list中一个fromkey的尾部移除一个值,添加到另外一个tokey的头部,并返回移除的值,阻塞时间为sp /// public string BlockingPopAndPushItemBetweenLists(string fromkey, string tokey, TimeSpan? sp) { return base.IClient.BlockingPopAndPushItemBetweenLists(fromkey, tokey, sp); } #endregion #region 删除 ////// 从尾部移除数据,返回移除的数据 /// public string PopItemFromList(string key) { var sa = base.IClient.CreateSubscription(); return base.IClient.PopItemFromList(key); } ////// 从尾部移除数据,返回移除的数据 /// public string DequeueItemFromList(string key) { return base.IClient.DequeueItemFromList(key); } ////// 移除list中,key/value,与参数相同的值,并返回移除的数量 /// public long RemoveItemFromList(string key, string value) { return base.IClient.RemoveItemFromList(key, value); } ////// 从list的尾部移除一个数据,返回移除的数据 /// public string RemoveEndFromList(string key) { return base.IClient.RemoveEndFromList(key); } ////// 从list的头部移除一个数据,返回移除的值 /// public string RemoveStartFromList(string key) { return base.IClient.RemoveStartFromList(key); } #endregion #region 其它 ////// 从一个list的尾部移除一个数据,添加到另外一个list的头部,并返回移动的值 /// public string PopAndPushItemBetweenLists(string fromKey, string toKey) { return base.IClient.PopAndPushItemBetweenLists(fromKey, toKey); } public void TrimList(string key, int start, int end) { base.IClient.TrimList(key, start, end); } #endregion #region 发布订阅 public void Publish(string channel, string message) { base.IClient.PublishMessage(channel, message); } public void Subscribe(string channel, ActionactionOnMessage) { var subscription = base.IClient.CreateSubscription(); subscription.OnSubscribe = c => { Console.WriteLine($"订阅频道{c}"); Console.WriteLine(); }; //取消订阅 subscription.OnUnSubscribe = c => { Console.WriteLine($"取消订阅 {c}"); Console.WriteLine(); }; subscription.OnMessage += (c, s) => { actionOnMessage(c, s, subscription); }; Console.WriteLine($"开始启动监听 {channel}"); subscription.SubscribeToChannels(channel); //blocking } public void UnSubscribeFromChannels(string channel) { var subscription = base.IClient.CreateSubscription(); subscription.UnSubscribeFromChannels(channel); } #endregion }
4.Set
////// Set:用哈希表来保持字符串的唯一性,没有先后顺序,存储一些集合性的数据 /// 1.共同好友、二度好友 /// 2.利用唯一性,可以统计访问网站的所有独立 IP /// public class RedisSetService : RedisBase { #region 添加 ////// key集合中添加value值 /// public void Add(string key, string value) { base.IClient.AddItemToSet(key, value); } ////// key集合中添加list集合 /// public void Add(string key, Listlist) { base.IClient.AddRangeToSet(key, list); } #endregion #region 获取 /// /// 随机获取key集合中的一个值 /// public string GetRandomItemFromSet(string key) { return base.IClient.GetRandomItemFromSet(key); } ////// 获取key集合值的数量 /// public long GetCount(string key) { return base.IClient.GetSetCount(key); } ////// 获取所有key集合的值 /// public HashSetGetAllItemsFromSet(string key) { return base.IClient.GetAllItemsFromSet(key); } #endregion #region 删除 /// /// 随机删除key集合中的一个值 /// public string RandomRemoveItemFromSet(string key) { return base.IClient.PopItemFromSet(key); } ////// 删除key集合中的value /// public void RemoveItemFromSet(string key, string value) { base.IClient.RemoveItemFromSet(key, value); } #endregion #region 其它 ////// 从fromkey集合中移除值为value的值,并把value添加到tokey集合中 /// public void MoveBetweenSets(string fromkey, string tokey, string value) { base.IClient.MoveBetweenSets(fromkey, tokey, value); } ////// 返回keys多个集合中的并集,返还hashset /// public HashSetGetUnionFromSets(params string[] keys) { return base.IClient.GetUnionFromSets(keys); } /// /// 返回keys多个集合中的交集,返还hashset /// public HashSetGetIntersectFromSets(params string[] keys) { return base.IClient.GetIntersectFromSets(keys); } /// /// 返回keys多个集合中的差集,返还hashset /// /// 原集合 /// 其他集合 ///出现在原集合,但不包含在其他集合 public HashSetGetDifferencesFromSet(string fromKey, params string[] keys) { return base.IClient.GetDifferencesFromSet(fromKey,keys); } /// /// keys多个集合中的并集,放入newkey集合中 /// public void StoreUnionFromSets(string newkey, string[] keys) { base.IClient.StoreUnionFromSets(newkey, keys); } ////// 把fromkey集合中的数据与keys集合中的数据对比,fromkey集合中不存在keys集合中,则把这些不存在的数据放入newkey集合中 /// public void StoreDifferencesFromSet(string newkey, string fromkey, string[] keys) { base.IClient.StoreDifferencesFromSet(newkey, fromkey, keys); } #endregion }
5.ZSet
////// Sorted Sets是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列 /// 1.带有权重的元素,比如一个游戏的用户得分排行榜 /// 2.比较复杂的数据结构,一般用到的场景不算太多 /// public class RedisZSetService : RedisBase { #region 添加 ////// 添加key/value,默认分数是从1.多*10的9次方以此递增的,自带自增效果 /// public bool Add(string key, string value) { return base.IClient.AddItemToSortedSet(key, value); } ////// 添加key/value,并设置value的分数 /// public bool AddItemToSortedSet(string key, string value, double score) { return base.IClient.AddItemToSortedSet(key, value, score); } ////// 为key添加values集合,values集合中每个value的分数设置为score /// public bool AddRangeToSortedSet(string key, Listvalues, double score) { return base.IClient.AddRangeToSortedSet(key, values, score); } /// /// 为key添加values集合,values集合中每个value的分数设置为score /// public bool AddRangeToSortedSet(string key, Listvalues, long score) { return base.IClient.AddRangeToSortedSet(key, values, score); } #endregion #region 获取 /// /// 获取key的所有集合 /// public ListGetAll(string key) { return base.IClient.GetAllItemsFromSortedSet(key); } /// /// 获取key的所有集合,倒叙输出 /// public ListGetAllDesc(string key) { return base.IClient.GetAllItemsFromSortedSetDesc(key); } /// /// 获取集合,带分数 /// public IDictionaryGetAllWithScoresFromSortedSet(string key) { return base.IClient.GetAllWithScoresFromSortedSet(key); } /// /// 获取key为value的下标值 /// public long GetItemIndexInSortedSet(string key, string value) { return base.IClient.GetItemIndexInSortedSet(key, value); } ////// 倒叙排列获取key为value的下标值 /// public long GetItemIndexInSortedSetDesc(string key, string value) { return base.IClient.GetItemIndexInSortedSetDesc(key, value); } ////// 获取key为value的分数 /// public double GetItemScoreInSortedSet(string key, string value) { return base.IClient.GetItemScoreInSortedSet(key, value); } ////// 获取key所有集合的数据总数 /// public long GetSortedSetCount(string key) { return base.IClient.GetSortedSetCount(key); } ////// key集合数据从分数为fromscore到分数为toscore的数据总数 /// public long GetSortedSetCount(string key, double fromScore, double toScore) { return base.IClient.GetSortedSetCount(key, fromScore, toScore); } ////// 获取key集合从高分到低分排序数据,分数从fromscore到分数为toscore的数据 /// public ListGetRangeFromSortedSetByHighestScore(string key, double fromscore, double toscore) { return base.IClient.GetRangeFromSortedSetByHighestScore(key, fromscore, toscore); } /// /// 获取key集合从低分到高分排序数据,分数从fromscore到分数为toscore的数据 /// public ListGetRangeFromSortedSetByLowestScore(string key, double fromscore, double toscore) { return base.IClient.GetRangeFromSortedSetByLowestScore(key, fromscore, toscore); } /// /// 获取key集合从高分到低分排序数据,分数从fromscore到分数为toscore的数据,带分数 /// public IDictionaryGetRangeWithScoresFromSortedSetByHighestScore(string key, double fromscore, double toscore) { return base.IClient.GetRangeWithScoresFromSortedSetByHighestScore(key, fromscore, toscore); } /// /// 获取key集合从低分到高分排序数据,分数从fromscore到分数为toscore的数据,带分数 /// public IDictionaryGetRangeWithScoresFromSortedSetByLowestScore(string key, double fromscore, double toscore) { return base.IClient.GetRangeWithScoresFromSortedSetByLowestScore(key, fromscore, toscore); } /// /// 获取key集合数据,下标从fromRank到分数为toRank的数据 /// public ListGetRangeFromSortedSet(string key, int fromRank, int toRank) { return base.IClient.GetRangeFromSortedSet(key, fromRank, toRank); } /// /// 获取key集合倒叙排列数据,下标从fromRank到分数为toRank的数据 /// public ListGetRangeFromSortedSetDesc(string key, int fromRank, int toRank) { return base.IClient.GetRangeFromSortedSetDesc(key, fromRank, toRank); } /// /// 获取key集合数据,下标从fromRank到分数为toRank的数据,带分数 /// public IDictionaryGetRangeWithScoresFromSortedSet(string key, int fromRank, int toRank) { return base.IClient.GetRangeWithScoresFromSortedSet(key, fromRank, toRank); } /// /// 获取key集合倒叙排列数据,下标从fromRank到分数为toRank的数据,带分数 /// public IDictionaryGetRangeWithScoresFromSortedSetDesc(string key, int fromRank, int toRank) { return base.IClient.GetRangeWithScoresFromSortedSetDesc(key, fromRank, toRank); } #endregion #region 删除 /// /// 删除key为value的数据 /// public bool RemoveItemFromSortedSet(string key, string value) { return base.IClient.RemoveItemFromSortedSet(key, value); } ////// 删除下标从minRank到maxRank的key集合数据 /// public long RemoveRangeFromSortedSet(string key, int minRank, int maxRank) { return base.IClient.RemoveRangeFromSortedSet(key, minRank, maxRank); } ////// 删除分数从fromscore到toscore的key集合数据 /// public long RemoveRangeFromSortedSetByScore(string key, double fromscore, double toscore) { return base.IClient.RemoveRangeFromSortedSetByScore(key, fromscore, toscore); } ////// 删除key集合中分数最大的数据 /// public string PopItemWithHighestScoreFromSortedSet(string key) { return base.IClient.PopItemWithHighestScoreFromSortedSet(key); } ////// 删除key集合中分数最小的数据 /// public string PopItemWithLowestScoreFromSortedSet(string key) { return base.IClient.PopItemWithLowestScoreFromSortedSet(key); } #endregion #region 其它 ////// 判断key集合中是否存在value数据 /// public bool SortedSetContainsItem(string key, string value) { return base.IClient.SortedSetContainsItem(key, value); } ////// 为key集合值为value的数据,分数加scoreby,返回相加后的分数 /// public double IncrementItemInSortedSet(string key, string value, double scoreBy) { return base.IClient.IncrementItemInSortedSet(key, value, scoreBy); } ////// 获取keys多个集合的交集,并把交集添加的newkey集合中,返回交集数据的总数 /// public long StoreIntersectFromSortedSets(string newkey, string[] keys) { return base.IClient.StoreIntersectFromSortedSets(newkey, keys); } ////// 获取keys多个集合的并集,并把并集数据添加到newkey集合中,返回并集数据的总数 /// public long StoreUnionFromSortedSets(string newkey, string[] keys) { return base.IClient.StoreUnionFromSortedSets(newkey, keys); } #endregion }