ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

封装redis方法

2020-10-23 17:02:23  阅读:172  来源: 互联网

标签:封装 string redis value static key return 方法 public


最近在自己的项目有使用到redis,一直使用别人封装的东西,今天想自己动手封装一下,顺便深入了解redis。

安装

我使用的StackExchange.Redis

GitHub:https://github.com/StackExchange/StackExchange.Redis/

安装最新版本就行

封装

官网有这样一句话

The central object in StackExchange.Redis is the ConnectionMultiplexer class in the StackExchange.Redis namespace; this is the object that hides away the details of multiple servers. Because the ConnectionMultiplexer does a lot, it is designed to be shared and reused between callers. You should not create a ConnectionMultiplexer per operation. It is fully thread-safe and ready for this usage. In all the subsequent examples it will be assumed that you have a ConnectionMultiplexer instance stored away for re-use. 

通过百度翻译

中心对象StackExchange.Redis中的ConnectionMultiplexer类StackExchange.Redis名称空间;这是隐藏多个服务器详细信息的对象。因为ConnectionMultiplexer做了很多事情,所以它被设计成在调用者之间共享和重用。不应为每个操作创建ConnectionMultiplexer。它是完全线程安全的,可以使用它。在后面的所有示例中,我们将假定您有一个ConnectionMultiplexer实例存储起来以供重用。

那我可以封装一个Redis连接类,这个类型可以单例模式封装成一个单例。

 public class RedisConnectionHelper
    {
        /// <summary>
        /// 连接redis server 类
        /// </summary>
        public static ConnectionMultiplexer _connection;
        public readonly static object _locker = new object();

        /// <summary>
        /// 缓存连接实例
        /// </summary>
        public static readonly Dictionary<string, ConnectionMultiplexer> _connectionCache =
            new Dictionary<string, ConnectionMultiplexer>();
        /// <summary>
        /// 连接实例  (单例模式)
        /// </summary>
        public static ConnectionMultiplexer Instance
        {

            get
            {

                if (_connection == null)
                {
                    lock (_locker)
                    {
                        if (_connection == null || !_connection.IsConnected)
                        {
                            _connection = CreateConnection();
                        }
                    }
                }
                return _connection;
            }
        }
        /// <summary>
        /// https://stackexchange.github.io/StackExchange.Redis/Basics
        /// </summary>
        /// <param name="connectionString"></param>
        public static ConnectionMultiplexer CreateConnection(string connectionString = null)
        {
            //连接字符串
            string connectStr = connectionString ?? "127.0.0.1:6379";
            ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(connectStr);
            //redis 事件注册
            redis.ConnectionFailed += Redis_ConnectionFailed;
            return redis;
        }

        public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString)
        {
            if (!_connectionCache.ContainsKey(connectionString))
            {
                _connectionCache[connectionString] = CreateConnection(connectionString);
            }
            return _connectionCache[connectionString];
        }
        /// <summary>
        /// redis 服务连接失败事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void Redis_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
        {
            Console.WriteLine(e.Exception);
        }
    }

实例化ConnectionMultiplexer对象之后,可以直接GetDatabase获取到Redis数据库对象(IDatabase类型)。

这其中有很多操作数据的方法,我每次在实例化Db之后再去调用方法,有点麻烦,再封装一个方法类,需要注意的是这里封装方法需要安装Newtonsoft.Json

这里为什么需要用到这跟呢,因为很多情况下,如果我需要缓存一个对象的时候,例如一个Student,那么这种情况下,Redis是没法直接存的,需要先Json化为string类型

然后再保存。

这里重点要注意的是操作list的方法,redis中的list是一个双向链表,list集合可以左右、中间插入元素。所以在这里在封装的时候还是有一些坑去爬的。

public static class RedisHelper
    {
        public static readonly ConnectionMultiplexer _connectin;
        /// <summary>
        /// 数据库id
        /// </summary>
        public static int DbNum { get; set; }
        /// <summary>
        /// 连接方式
        /// </summary>
        public static string ConnectionString { get; set; }

        static RedisHelper()
        {
            DbNum = -1;
            ConnectionString = null;
            _connectin = string.IsNullOrEmpty(ConnectionString) ?
                   RedisConnectionHelper.Instance :
                   RedisConnectionHelper.GetConnectionMultiplexer(ConnectionString);
        }
        /// <summary>
        /// 获取db
        /// </summary>
        public static IDatabase Db
        {
            get
            {
                return _connectin.GetDatabase(DbNum);
            }
        }
        /// <summary>
        /// 执行委托
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="func"></param>
        /// <returns></returns>
        public static T Do<T>(Func<IDatabase, T> func)
        {
            return func(Db);
        }
        #region string
        /// <summary>
        /// 保存string
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="expiry"></param>
        public static bool StringSet(string key, string value, TimeSpan? expiry = null)
        {
            return Do(d => d.StringSet(key, value,expiry));
        }

        /// <summary>
        /// 异步保存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        public static async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = null)
        {
            return await Do(d => d.StringSetAsync(key, value, expiry));
        }
        /// <summary>
        /// 获取值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string StringGet(string key)
        {
            return Do(d => d.StringGet(key));
        }

        /// <summary>
        /// 获取值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static async Task<string> StringGetAsync(string key)
        {
            return await Do(d => d.StringGetAsync(key));
        }
        /// <summary>
        /// 删除键
        /// </summary>
        /// <param name="key"></param>
        public static bool KeyDelete(string key)
        {
            return Do(d => d.KeyDelete(key));
        }

        /// <summary>
        /// 删除键
        /// </summary>
        /// <param name="key"></param>
        public static async Task<bool> KeyDeleteAsync(string key)
        {
            return await Do(d => d.KeyDeleteAsync(key));
        }
        /// <summary>
        /// set
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        public static bool StringSet<T>(string key, T value, TimeSpan? expiry = null)
        {
            string json = Serialize(value);
            return Do(d => d.StringSet(key, json, expiry));
        }

        /// <summary>
        /// set
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        public static async Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null)
        {
            string json = Serialize(value);
            return await Do(d => d.StringSetAsync(key, json, expiry));
        }
        /// <summary>
        /// get 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        public static T StringGet<T>(string key)
        {
            string json = Do(d => d.StringGet(key)).ToString();
            return Deserialize<T>(json);
        }

        /// <summary>
        /// get 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        public static async Task<T> StringGetAsync<T>(string key)
        {
            string json = await Do(d => d.StringGetAsync(key));
            return Deserialize<T>(json);
        }
        #endregion
        /// <summary>
        /// 序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        private static string Serialize<T>(T value)
        {
            var result = value is string ? value.ToString() : JsonConvert.SerializeObject(value,
                new JsonSerializerSettings
                {
                    DateFormatString = "yyyy-MM-dd hh:mm:ss"
                });
            return result;
        }
        /// <summary>
        /// 解析
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        private static T Deserialize<T>(string json)
        {
            if (string.IsNullOrEmpty(json)) return default;
            return JsonConvert.DeserializeObject<T>(json);
        }
        /// <summary>
        /// 解析redis缓存的集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="values"></param>
        /// <returns></returns>
        private static List<T> DeserializeList<T>(RedisValue[] values)
        {
            return values.Select(s => Deserialize<T>(s)).ToList();
        }

        #region List
        /// <summary>
        /// 保存list 集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void SetList<T>(string key, List<T> value)
        {
            if (value.Count > 0)
            {
                var values = value.Select(s => (RedisValue)Serialize(s)).ToArray();
                Do(d => d.ListRightPush(key, values));
            }
        }

        /// <summary>
        /// 保存list 集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static async Task SetListAsync<T>(string key, List<T> value)
        {
            if (value.Count > 0)
            {
                var values = value.Select(s => (RedisValue)Serialize(s)).ToArray();
                await Do(d => d.ListRightPushAsync(key, values));
            }
        }
        /// <summary>
        /// 获取list 集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static List<T> GetList<T>(string key)
        {
            var values = Do(d => d.ListRange(key));
            if (values.IsNullOrEmpty())
            {
                return values.Select(s => Deserialize<T>(s)).ToList();
            }
            return default;
        }
        /// <summary>
        /// 获取list 集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static async Task<List<T>> GetListAsync<T>(string key)
        {
            var values = await Do(d => d.ListRangeAsync(key));
            if (values.IsNullOrEmpty())
            {
                return values.Select(s => Deserialize<T>(s)).ToList();
            }
            return default;
        }
        /// <summary>
        /// 删除并返回集合的第一个元素
        /// ListLeftPop
        /// </summary>
        /// <param name="key"></param>
        public static T RemoveFirst<T>(string key)
        {
            var json = Do(d => d.ListLeftPop(key));
            return Deserialize<T>(json);
        }
        /// <summary>
        /// 删除并返回集合的第一个元素
        /// ListLeftPop
        /// </summary>
        /// <param name="key"></param>
        public static async Task<T> RemoveFirstAsync<T>(string key)
        {
            var json = await Do(d => d.ListLeftPopAsync(key));
            return Deserialize<T>(json);
        }
        /// <summary>
        /// 删除并返回集合的最后一个元素
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T RemoveLast<T>(string key)
        {
            return Deserialize<T>(Do(d => d.ListRightPop(key)));
        }

        /// <summary>
        /// 删除并返回集合的最后一个元素
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static async Task<T> RemoveLastAsync<T>(string key)
        {
            return Deserialize<T>(await Do(d => d.ListRightPopAsync(key)));
        }
        /// <summary>
        /// 根据索引获取集合 (默认所有)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        public static List<T> ListRange<T>(string key, long start = 0, long stop = -1)
        {
            var json = Do(d => d.ListRange(key, start, stop));
            return DeserializeList<T>(json);
        }

        /// <summary>
        /// 根据索引获取集合 (默认所有)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        public static async Task<List<T>> ListRangeAsync<T>(string key, long start = 0, long stop = -1)
        {
            var json = await Do(d => d.ListRangeAsync(key, start, stop));
            return DeserializeList<T>(json);
        }

        /// <summary>
        /// 根据元素删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回删除元素数量</returns>
        public static int RemoveAt<T>(string key,T value)
        {
            return (int)Do(d => d.ListRemove(key, Serialize(value)));
        }

        /// <summary>
        /// 根据元素删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回删除元素数量</returns>
        public static async Task<int> RemoveAtAsync<T>(string key, T value)
        {
            return (int)await Do(d => d.ListRemoveAsync(key, Serialize(value)));
        }
        /// <summary>
        /// 向集合开头添加一个元素
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void AddFirst<T>(string key, T value)
        {
            Do(d => d.ListLeftPush(key, Serialize(value)));
        }
        /// <summary>
        /// 向集合开头添加一个元素
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static async Task AddFirstAsync<T>(string key, T value)
        {
            await Do(d => d.ListLeftPushAsync(key, Serialize(value)));
        }
        /// <summary>
        /// 向集合末尾添加一个元素
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void AddLast<T>(string key, T value)
        {
            Do(d => d.ListRightPush(key, Serialize(value)));
        }
        /// <summary>
        /// 向集合末尾添加一个元素
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>

        public static async Task AddLastAsync<T>(string key, T value)
        {
            await Do(d => d.ListRightPushAsync(key, Serialize(value)));
        }
        /// <summary>
        /// 判断对象是否存在
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool Contains<T>(string key, T value)
        {
            //数量
            var length = Count(key);
            //格式话对象
            var json = Serialize(value);
            for (int i = 0; i < length; i++)
            {
                if (Do(d => d.ListGetByIndex(key, i).ToString().Equals(json)))
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 判断对象是否存在
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static async Task<bool> ContainsAsync<T>(string key, T value)
        {
            //数量
            var length = await CountAsync(key);
            //格式话对象
            var json = Serialize(value);
            for (int i = 0; i < length; i++)
            {
                var item = await Do(d => d.ListGetByIndexAsync(key, i));
                if (item.ToString().Equals(json))
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 根据索引获取对象
        /// ListGetByIndex
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static T Get<T>(string key, int index)
        {
            string json = Do(d => d.ListGetByIndex(key, index));
            return Deserialize<T>(json);
        }

        /// <summary>
        /// 根据索引获取对象
        /// ListGetByIndex
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static async Task<T> GetAsync<T>(string key, int index)
        {
            string json = await Do(d => d.ListGetByIndexAsync(key, index));
            return Deserialize<T>(json);
        }
        /// <summary>
        /// 根据对象获取索引
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static int IndexOf<T>(string key, T value)
        {
            //数量
            var length = Count(key);
            //格式话对象
            var json = Serialize(value);
            for (int i = 0; i < length; i++)
            {
                if ( Do(d => d.ListGetByIndex(key, i).ToString().Equals(json)))
                {
                    return i;
                }
            }
            return -1;
        }

        /// <summary>
        /// 根据对象获取索引
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static async Task<int> IndexOfAsync<T>(string key, T value)
        {
            //数量
            var length = await CountAsync(key);
            //格式话对象
            var json = Serialize(value);
            for (int i = 0; i < length; i++)
            {
                var item = await Do(d => d.ListGetByIndexAsync(key, i));
                if ( item.ToString().Equals(json))
                {
                    return i;
                }
            }
            return -1;
        }
        /// <summary>
        /// 获取list的数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static int Count(string key)
        {
            return (int)Do(d => d.ListLength(key));
        }

        /// <summary>
        /// 获取list的数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static async Task<int> CountAsync(string key)
        {
            return (int)await Do(d => d.ListLengthAsync(key));
        }
        #endregion
    }

总结

很多东西需要自己动手去试试才能获得更多知识。

 封装GitHub:https://github.com/QQ2287991080/Zero.Core/tree/master/src/Zero.Core.Common/Redis

测试GitHub:https://github.com/QQ2287991080/Zero.Core/blob/master/src/Zero.Core.xUnitTest/Redis/RedisTest.cs

标签:封装,string,redis,value,static,key,return,方法,public
来源: https://www.cnblogs.com/aqgy12138/p/13864970.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有