• 封装redis方法


    最近在自己的项目有使用到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

  • 相关阅读:
    mongodb的aggregate聚合操作详解
    2013, Lost connection to MySQL server during query
    事务失败的重试策略
    mongodb的shell脚本
    mongodb的currentOp
    mongodb插入数据
    Too many threads are already waiting
    connection timed out
    python3-request.session 的使用
    intellij-永久破解最新版本idea 2020.3.1
  • 原文地址:https://www.cnblogs.com/aqgy12138/p/13864970.html
Copyright © 2020-2023  润新知