前两天朋友问我,有没有使用过StackExchange.Redis,问我要个封装类,由于之前都是使用ServiceStack.Redis,由于ServiceStack.Redis v4版本后是收费版的,所以现在也很有公司都在使用StackExchange.Redis而抛弃ServiceStack.Redis了。其实个人觉得,两个驱动都不错,只是由于ServiceStack.Redis收费导致目前很多公司都是基于V3版本的使用,也有人说V3版本有很多Bug,没有维护和升级,不过至少目前我是没发现Bug。
不过ServiceStack.Redis同StackExchange.Redis比较,抛开收费的来说,确认比StackExchange.Redis 更有优势。StackExchange.Redis文档很少,更不要说国内的文档了,连github上面对应的介绍文档都是很片面,这点我真的觉得StackExchange.Redis的作者至少要完善下文档,很多都是要看源码的例子才有。网上对StackExchange.Redis的使用例子也比ServiceStack.Redis少得多,不是说没人用,只是我查来查去,大部分都是基于String类型的数据进行使用的封装类,对于List,SortedSet,Hash的封装操作都很少,基本都是东写一点,西写一点,很难找到完整的。在参考了一些文章和源码后,这里提供一个自己封装的类,基本提供对于各种类型的使用封装,提供给大家学习使用,如果有哪里写的不好的,大家也可以互相交流。
ConnectionMultiplexer 封装
首先是 ConnectionMultiplexer 的封装,ConnectionMultiplexer对象是StackExchange.Redis最中枢的对象。这个类的实例需要被整个应用程序域共享和重用的,所以不需要在每个操作中不停的创建该对象的实例,一般都是使用单例来创建和存放这个对象,这个在官网上也有说明。
1 ///2 /// ConnectionMultiplexer对象管理帮助类 3 /// 4 public static class RedisConnectionHelp 5 { 6 //系统自定义Key前缀 7 public static readonly string SysCustomKey = ConfigurationManager.AppSettings["redisKey"] ?? ""; 8 9 //"127.0.0.1:6379,allowadmin=true 10 private static readonly string RedisConnectionString = ConfigurationManager.ConnectionStrings["RedisExchangeHosts"].ConnectionString; 11 12 private static readonly object Locker = new object(); 13 private static ConnectionMultiplexer _instance; 14 private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string, ConnectionMultiplexer>(); 15 16 /// 17 /// 单例获取 18 /// 19 public static ConnectionMultiplexer Instance 20 { 21 get 22 { 23 if (_instance == null) 24 { 25 lock (Locker) 26 { 27 if (_instance == null || !_instance.IsConnected) 28 { 29 _instance = GetManager(); 30 } 31 } 32 } 33 return _instance; 34 } 35 } 36 37 /// 38 /// 缓存获取 39 /// 40 /// 41 /// 42 public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString) 43 { 44 if (!ConnectionCache.ContainsKey(connectionString)) 45 { 46 ConnectionCache[connectionString] = GetManager(connectionString); 47 } 48 return ConnectionCache[connectionString]; 49 } 50 51 private static ConnectionMultiplexer GetManager(string connectionString = null) 52 { 53 connectionString = connectionString ?? RedisConnectionString; 54 var connect = ConnectionMultiplexer.Connect(connectionString); 55 56 //注册如下事件 57 connect.ConnectionFailed += MuxerConnectionFailed; 58 connect.ConnectionRestored += MuxerConnectionRestored; 59 connect.ErrorMessage += MuxerErrorMessage; 60 connect.ConfigurationChanged += MuxerConfigurationChanged; 61 connect.HashSlotMoved += MuxerHashSlotMoved; 62 connect.InternalError += MuxerInternalError; 63 64 return connect; 65 } 66 67 #region 事件 68 69 /// 70 /// 配置更改时 71 /// 72 /// 73 /// 74 private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e) 75 { 76 Console.WriteLine("Configuration changed: " + e.EndPoint); 77 } 78 79 /// 80 /// 发生错误时 81 /// 82 /// 83 /// 84 private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e) 85 { 86 Console.WriteLine("ErrorMessage: " + e.Message); 87 } 88 89 /// 90 /// 重新建立连接之前的错误 91 /// 92 /// 93 /// 94 private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e) 95 { 96 Console.WriteLine("ConnectionRestored: " + e.EndPoint); 97 } 98 99 /// 100 /// 连接失败 , 如果重新连接成功你将不会收到这个通知 101 /// 102 /// 103 /// 104 private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e) 105 { 106 Console.WriteLine("重新连接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message))); 107 } 108 109 /// 110 /// 更改集群 111 /// 112 /// 113 /// 114 private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e) 115 { 116 Console.WriteLine("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint); 117 } 118 119 /// 120 /// redis类库错误 121 /// 122 /// 123 /// 124 private static void MuxerInternalError(object sender, InternalErrorEventArgs e) 125 { 126 Console.WriteLine("InternalError:Message" + e.Exception.Message); 127 } 128 129 #endregion 事件 130 }
RedisHelper 通用操作类封
1 public class RedisHelper 2 { 3 private int DbNum { get; } 4 private readonly ConnectionMultiplexer _conn; 5 public string CustomKey; 6 7 #region 构造函数 8 9 public RedisHelper(int dbNum = 0) 10 : this(dbNum, null) 11 { 12 } 13 14 public RedisHelper(int dbNum, string readWriteHosts) 15 { 16 DbNum = dbNum; 17 _conn = 18 string.IsNullOrWhiteSpace(readWriteHosts) ? 19 RedisConnectionHelp.Instance : 20 RedisConnectionHelp.GetConnectionMultiplexer(readWriteHosts); 21 } 22 23 #region 辅助方法 24 25 private string AddSysCustomKey(string oldKey) 26 { 27 var prefixKey = CustomKey ?? RedisConnectionHelp.SysCustomKey; 28 return prefixKey + oldKey; 29 } 30 31 private T Do(Func func) 32 { 33 var database = _conn.GetDatabase(DbNum); 34 return func(database); 35 } 36 37 private string ConvertJson (T value) 38 { 39 string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value); 40 return result; 41 } 42 43 private T ConvertObj (RedisValue value) 44 { 45 return JsonConvert.DeserializeObject (value); 46 } 47 48 private List ConvetList (RedisValue[] values) 49 { 50 List result = new List (); 51 foreach (var item in values) 52 { 53 var model = ConvertObj (item); 54 result.Add(model); 55 } 56 return result; 57 } 58 59 private RedisKey[] ConvertRedisKeys(List<string> redisKeys) 60 { 61 return redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray(); 62 } 63 64 #endregion 辅助方法 65 66 #endregion 构造函数 67 }
其中CustomKey用来表示系统前缀,AddSysCustomKey方法对每个key都进行前缀的添加处理,这里推荐大家在命名redis的key的时候最好的加上前缀,并且使用 :来分割前缀 ,这里在使用可视化工具查看的时候就比较好区分,比如我的的前缀是 Demo:test:(一般是 系统名:业务名:),然后你查看的时候你会发现整齐,好区分了很多
String类型的封装
1 #region String 2 3 #region 同步方法 4 5 ///6 /// 保存单个key value 7 /// 8 /// Redis Key 9 /// 保存的值 10 /// 过期时间 11 /// 12 public bool StringSet(string key, string value, TimeSpan? expiry = default(TimeSpan?)) 13 { 14 key = AddSysCustomKey(key); 15 return Do(db => db.StringSet(key, value, expiry)); 16 } 17 18 /// 19 /// 保存多个key value 20 /// 21 /// 键值对 22 /// 23 public bool StringSet(List > keyValues) 24 { 25 List > newkeyValues = 26 keyValues.Select(p => new KeyValuePair (AddSysCustomKey(p.Key), p.Value)).ToList(); 27 return Do(db => db.StringSet(newkeyValues.ToArray())); 28 } 29 30 /// 31 /// 保存一个对象 32 /// 33 /// 34 /// 35 /// 36 /// 37 /// 38 public bool StringSet (string key, T obj, TimeSpan? expiry = default(TimeSpan?)) 39 { 40 key = AddSysCustomKey(key); 41 string json = ConvertJson(obj); 42 return Do(db => db.StringSet(key, json, expiry)); 43 } 44 45 /// 46 /// 获取单个key的值 47 /// 48 /// Redis Key 49 /// 50 public string StringGet(string key) 51 { 52 key = AddSysCustomKey(key); 53 return Do(db => db.StringGet(key)); 54 } 55 56 /// 57 /// 获取多个Key 58 /// 59 /// Redis Key集合 60 /// 61 public RedisValue[] StringGet(List<string> listKey) 62 { 63 List<string> newKeys = listKey.Select(AddSysCustomKey).ToList(); 64 return Do(db => db.StringGet(ConvertRedisKeys(newKeys))); 65 } 66 67 /// 68 /// 获取一个key的对象 69 /// 70 /// 71 /// 72 /// 73 public T StringGet (string key) 74 { 75 key = AddSysCustomKey(key); 76 return Do(db => ConvertObj (db.StringGet(key))); 77 } 78 79 /// 80 /// 为数字增长val 81 /// 82 /// 83 /// 可以为负 84 /// 增长后的值 85 public double StringIncrement(string key, double val = 1) 86 { 87 key = AddSysCustomKey(key); 88 return Do(db => db.StringIncrement(key, val)); 89 } 90 91 /// 92 /// 为数字减少val 93 /// 94 /// 95 /// 可以为负 96 /// 减少后的值 97 public double StringDecrement(string key, double val = 1) 98 { 99 key = AddSysCustomKey(key); 100 return Do(db => db.StringDecrement(key, val)); 101 } 102 103 #endregion 同步方法 104 105 #region 异步方法 106 107 /// 108 /// 保存单个key value 109 /// 110 /// Redis Key 111 /// 保存的值 112 /// 过期时间 113 /// 114 public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = default(TimeSpan?)) 115 { 116 key = AddSysCustomKey(key); 117 return await Do(db => db.StringSetAsync(key, value, expiry)); 118 } 119 120 /// 121 /// 保存多个key value 122 /// 123 /// 键值对 124 /// 125 public async Task<bool> StringSetAsync(List > keyValues) 126 { 127 List > newkeyValues = 128 keyValues.Select(p => new KeyValuePair (AddSysCustomKey(p.Key), p.Value)).ToList(); 129 return await Do(db => db.StringSetAsync(newkeyValues.ToArray())); 130 } 131 132 /// 133 /// 保存一个对象 134 /// 135 /// 136 /// 137 /// 138 /// 139 /// 140 public async Task<bool> StringSetAsync (string key, T obj, TimeSpan? expiry = default(TimeSpan?)) 141 { 142 key = AddSysCustomKey(key); 143 string json = ConvertJson(obj); 144 return await Do(db => db.StringSetAsync(key, json, expiry)); 145 } 146 147 /// 148 /// 获取单个key的值 149 /// 150 /// Redis Key 151 /// 152 public async Task<string> StringGetAsync(string key) 153 { 154 key = AddSysCustomKey(key); 155 return await Do(db => db.StringGetAsync(key)); 156 } 157 158 /// 159 /// 获取多个Key 160 /// 161 /// Redis Key集合 162 /// 163 public async Task StringGetAsync(List<string> listKey) 164 { 165 List<string> newKeys = listKey.Select(AddSysCustomKey).ToList(); 166 return await Do(db => db.StringGetAsync(ConvertRedisKeys(newKeys))); 167 } 168 169 /// 170 /// 获取一个key的对象 171 /// 172 /// 173 /// 174 /// 175 public async Task StringGetAsync (string key) 176 { 177 key = AddSysCustomKey(key); 178 string result = await Do(db => db.StringGetAsync(key)); 179 return ConvertObj (result); 180 } 181 182 /// 183 /// 为数字增长val 184 /// 185 /// 186 /// 可以为负 187 /// 增长后的值 188 public async Task<double> StringIncrementAsync(string key, double val = 1) 189 { 190 key = AddSysCustomKey(key); 191 return await Do(db => db.StringIncrementAsync(key, val)); 192 } 193 194 /// 195 /// 为数字减少val 196 /// 197 /// 198 /// 可以为负 199 /// 减少后的值 200 public async Task<double> StringDecrementAsync(string key, double val = 1) 201 { 202 key = AddSysCustomKey(key); 203 return await Do(db => db.StringDecrementAsync(key, val)); 204 } 205 206 #endregion 异步方法 207 208 #endregion String
这里说一下,StackExchange.Redis 中对对象的存储是不自带序列化和反序列化的方法,所以在ConvertJson和ConvertObj里面我是使用了JsonConvert来操作,如果需要换成其他的序列化和序列化,直接修改这两个方面就好了,另外,StackExchange.Redis 相对于ServiceStack.Redis 来说提供了异步的方法,所以这里也同样封装了异步和同步的方法。
List类型的封装
1 #region List 2 3 #region 同步方法 4 5 ///6 /// 移除指定ListId的内部List的值 7 /// 8 /// 9 /// 10 public void ListRemove (string key, T value) 11 { 12 key = AddSysCustomKey(key); 13 Do(db => db.ListRemove(key, ConvertJson(value))); 14 } 15 16 /// 17 /// 获取指定key的List 18 /// 19 /// 20 /// 21 public List ListRange (string key) 22 { 23 key = AddSysCustomKey(key); 24 return Do(redis => 25 { 26 var values = redis.ListRange(key); 27 return ConvetList (values); 28 }); 29 } 30 31 /// 32 /// 入队 33 /// 34 /// 35 /// 36 public void ListRightPush (string key, T value) 37 { 38 key = AddSysCustomKey(key); 39 Do(db => db.ListRightPush(key, ConvertJson(value))); 40 } 41 42 /// 43 /// 出队 44 /// 45 /// 46 /// 47 /// 48 public T ListRightPop (string key) 49 { 50 key = AddSysCustomKey(key); 51 return Do(db => 52 { 53 var value = db.ListRightPop(key); 54 return ConvertObj (value); 55 }); 56 } 57 58 /// 59 /// 入栈 60 /// 61 /// 62 /// 63 /// 64 public void ListLeftPush (string key, T value) 65 { 66 key = AddSysCustomKey(key); 67 Do(db => db.ListLeftPush(key, ConvertJson(value))); 68 } 69 70 /// 71 /// 出栈 72 /// 73 /// 74 /// 75 /// 76 public T ListLeftPop (string key) 77 { 78 key = AddSysCustomKey(key); 79 return Do(db => 80 { 81 var value = db.ListLeftPop(key); 82 return ConvertObj (value); 83 }); 84 } 85 86 /// 87 /// 获取集合中的数量 88 /// 89 /// 90 /// 91 public long ListLength(string key) 92 { 93 key = AddSysCustomKey(key); 94 return Do(redis => redis.ListLength(key)); 95 } 96 97 #endregion 同步方法 98 99 #region 异步方法 100 101 /// 102 /// 移除指定ListId的内部List的值 103 /// 104 /// 105 /// 106 public async Task<long> ListRemoveAsync (string key, T value) 107 { 108 key = AddSysCustomKey(key); 109 return await Do(db => db.ListRemoveAsync(key, ConvertJson(value))); 110 } 111 112 /// 113 /// 获取指定key的List 114 /// 115 /// 116 /// 117 public async Task > ListRangeAsync
(string key) 118 { 119 key = AddSysCustomKey(key); 120 var values = await Do(redis => redis.ListRangeAsync(key)); 121 return ConvetList (values); 122 } 123 124 /// 125 /// 入队 126 /// 127 /// 128 /// 129 public async Task<long> ListRightPushAsync (string key, T value) 130 { 131 key = AddSysCustomKey(key); 132 return await Do(db => db.ListRightPushAsync(key, ConvertJson(value))); 133 } 134 135 /// 136 /// 出队 137 /// 138 /// 139 /// 140 /// 141 public async Task ListRightPopAsync (string key) 142 { 143 key = AddSysCustomKey(key); 144 var value = await Do(db => db.ListRightPopAsync(key)); 145 return ConvertObj (value); 146 } 147 148 /// 149 /// 入栈 150 /// 151 /// 152 /// 153 /// 154 public async Task<long> ListLeftPushAsync (string key, T value) 155 { 156 key = AddSysCustomKey(key); 157 return await Do(db => db.ListLeftPushAsync(key, ConvertJson(value))); 158 } 159 160 /// 161 /// 出栈 162 /// 163 /// 164 /// 165 /// 166 public async Task ListLeftPopAsync (string key) 167 { 168 key = AddSysCustomKey(key); 169 var value = await Do(db => db.ListLeftPopAsync(key)); 170 return ConvertObj (value); 171 } 172 173 /// 174 /// 获取集合中的数量 175 /// 176 /// 177 /// 178 public async Task<long> ListLengthAsync(string key) 179 { 180 key = AddSysCustomKey(key); 181 return await Do(redis => redis.ListLengthAsync(key)); 182 } 183 184 #endregion 异步方法 185 186 #endregion List
Hash类型的封装
1 #region Hash 2 3 #region 同步方法 4 5 ///6 /// 判断某个数据是否已经被缓存 7 /// 8 /// 9 /// 10 /// 11 public bool HashExists(string key, string dataKey) 12 { 13 key = AddSysCustomKey(key); 14 return Do(db => db.HashExists(key, dataKey)); 15 } 16 17 /// 18 /// 存储数据到hash表 19 /// 20 /// 21 /// 22 /// 23 /// 24 /// 25 public bool HashSet (string key, string dataKey, T t) 26 { 27 key = AddSysCustomKey(key); 28 return Do(db => 29 { 30 string json = ConvertJson(t); 31 return db.HashSet(key, dataKey, json); 32 }); 33 } 34 35 /// 36 /// 移除hash中的某值 37 /// 38 /// 39 /// 40 /// 41 public bool HashDelete(string key, string dataKey) 42 { 43 key = AddSysCustomKey(key); 44 return Do(db => db.HashDelete(key, dataKey)); 45 } 46 47 /// 48 /// 移除hash中的多个值 49 /// 50 /// 51 /// 52 /// 53 public long HashDelete(string key, List dataKeys) 54 { 55 key = AddSysCustomKey(key); 56 //List dataKeys1 = new List 57 return Do(db => db.HashDelete(key, dataKeys.ToArray())); 58 } 59 60 ///() {"1","2"}; 61 /// 从hash表获取数据 62 /// 63 /// 64 /// 65 /// 66 /// 67 public T HashGet (string key, string dataKey) 68 { 69 key = AddSysCustomKey(key); 70 return Do(db => 71 { 72 string value = db.HashGet(key, dataKey); 73 return ConvertObj (value); 74 }); 75 } 76 77 /// 78 /// 为数字增长val 79 /// 80 /// 81 /// 82 /// 可以为负 83 /// 增长后的值 84 public double HashIncrement(string key, string dataKey, double val = 1) 85 { 86 key = AddSysCustomKey(key); 87 return Do(db => db.HashIncrement(key, dataKey, val)); 88 } 89 90 /// 91 /// 为数字减少val 92 /// 93 /// 94 /// 95 /// 可以为负 96 /// 减少后的值 97 public double HashDecrement(string key, string dataKey, double val = 1) 98 { 99 key = AddSysCustomKey(key); 100 return Do(db => db.HashDecrement(key, dataKey, val)); 101 } 102 103 /// 104 /// 获取hashkey所有Redis key 105 /// 106 /// 107 /// 108 /// 109 public List HashKeys (string key) 110 { 111 key = AddSysCustomKey(key); 112 return Do(db => 113 { 114 RedisValue[] values = db.HashKeys(key); 115 return ConvetList (values); 116 }); 117 } 118 119 #endregion 同步方法 120 121 #region 异步方法 122 123 /// 124 /// 判断某个数据是否已经被缓存 125 /// 126 /// 127 /// 128 /// 129 public async Task<bool> HashExistsAsync(string key, string dataKey) 130 { 131 key = AddSysCustomKey(key); 132 return await Do(db => db.HashExistsAsync(key, dataKey)); 133 } 134 135 /// 136 /// 存储数据到hash表 137 /// 138 /// 139 /// 140 /// 141 /// 142 /// 143 public async Task<bool> HashSetAsync (string key, string dataKey, T t) 144 { 145 key = AddSysCustomKey(key); 146 return await Do(db => 147 { 148 string json = ConvertJson(t); 149 return db.HashSetAsync(key, dataKey, json); 150 }); 151 } 152 153 /// 154 /// 移除hash中的某值 155 /// 156 /// 157 /// 158 /// 159 public async Task<bool> HashDeleteAsync(string key, string dataKey) 160 { 161 key = AddSysCustomKey(key); 162 return await Do(db => db.HashDeleteAsync(key, dataKey)); 163 } 164 165 /// 166 /// 移除hash中的多个值 167 /// 168 /// 169 /// 170 /// 171 public async Task<long> HashDeleteAsync(string key, List dataKeys) 172 { 173 key = AddSysCustomKey(key); 174 //List dataKeys1 = new List 175 return await Do(db => db.HashDeleteAsync(key, dataKeys.ToArray())); 176 } 177 178 ///() {"1","2"}; 179 /// 从hash表获取数据 180 /// 181 /// 182 /// 183 /// 184 /// 185 public async Task HashGeAsync (string key, string dataKey) 186 { 187 key = AddSysCustomKey(key); 188 string value = await Do(db => db.HashGetAsync(key, dataKey)); 189 return ConvertObj (value); 190 } 191 192 /// 193 /// 为数字增长val 194 /// 195 /// 196 /// 197 /// 可以为负 198 /// 增长后的值 199 public async Task<double> HashIncrementAsync(string key, string dataKey, double val = 1) 200 { 201 key = AddSysCustomKey(key); 202 return await Do(db => db.HashIncrementAsync(key, dataKey, val)); 203 } 204 205 /// 206 /// 为数字减少val 207 /// 208 /// 209 /// 210 /// 可以为负 211 /// 减少后的值 212 public async Task<double> HashDecrementAsync(string key, string dataKey, double val = 1) 213 { 214 key = AddSysCustomKey(key); 215 return await Do(db => db.HashDecrementAsync(key, dataKey, val)); 216 } 217 218 /// 219 /// 获取hashkey所有Redis key 220 /// 221 /// 222 /// 223 /// 224 public async Task > HashKeysAsync
(string key) 225 { 226 key = AddSysCustomKey(key); 227 RedisValue[] values = await Do(db => db.HashKeysAsync(key)); 228 return ConvetList (values); 229 } 230 231 #endregion 异步方法 232 233 #endregion Hash
SortedSet 类型的封装
1 #region SortedSet 有序集合 2 3 #region 同步方法 4 5 ///6 /// 添加 7 /// 8 /// 9 /// 10 /// 11 public bool SortedSetAdd (string key, T value, double score) 12 { 13 key = AddSysCustomKey(key); 14 return Do(redis => redis.SortedSetAdd(key, ConvertJson (value), score)); 15 } 16 17 /// 18 /// 删除 19 /// 20 /// 21 /// 22 public bool SortedSetRemove (string key, T value) 23 { 24 key = AddSysCustomKey(key); 25 return Do(redis => redis.SortedSetRemove(key, ConvertJson(value))); 26 } 27 28 /// 29 /// 获取全部 30 /// 31 /// 32 /// 33 public List SortedSetRangeByRank (string key) 34 { 35 key = AddSysCustomKey(key); 36 return Do(redis => 37 { 38 var values = redis.SortedSetRangeByRank(key); 39 return ConvetList (values); 40 }); 41 } 42 43 /// 44 /// 获取集合中的数量 45 /// 46 /// 47 /// 48 public long SortedSetLength(string key) 49 { 50 key = AddSysCustomKey(key); 51 return Do(redis => redis.SortedSetLength(key)); 52 } 53 54 #endregion 同步方法 55 56 #region 异步方法 57 58 /// 59 /// 添加 60 /// 61 /// 62 /// 63 /// 64 public async Task<bool> SortedSetAddAsync (string key, T value, double score) 65 { 66 key = AddSysCustomKey(key); 67 return await Do(redis => redis.SortedSetAddAsync(key, ConvertJson (value), score)); 68 } 69 70 /// 71 /// 删除 72 /// 73 /// 74 /// 75 public async Task<bool> SortedSetRemoveAsync (string key, T value) 76 { 77 key = AddSysCustomKey(key); 78 return await Do(redis => redis.SortedSetRemoveAsync(key, ConvertJson(value))); 79 } 80 81 /// 82 /// 获取全部 83 /// 84 /// 85 /// 86 public async Task > SortedSetRangeByRankAsync
(string key) 87 { 88 key = AddSysCustomKey(key); 89 var values = await Do(redis => redis.SortedSetRangeByRankAsync(key)); 90 return ConvetList (values); 91 } 92 93 /// 94 /// 获取集合中的数量 95 /// 96 /// 97 /// 98 public async Task<long> SortedSetLengthAsync(string key) 99 { 100 key = AddSysCustomKey(key); 101 return await Do(redis => redis.SortedSetLengthAsync(key)); 102 } 103 104 #endregion 异步方法 105 106 #endregion SortedSet 有序集合
key的管理
1 #region key 2 3 ///4 /// 删除单个key 5 /// 6 /// redis key 7 /// 是否删除成功 8 public bool KeyDelete(string key) 9 { 10 key = AddSysCustomKey(key); 11 return Do(db => db.KeyDelete(key)); 12 } 13 14 /// 15 /// 删除多个key 16 /// 17 /// rediskey 18 /// 成功删除的个数 19 public long KeyDelete(List<string> keys) 20 { 21 List<string> newKeys = keys.Select(AddSysCustomKey).ToList(); 22 return Do(db => db.KeyDelete(ConvertRedisKeys(newKeys))); 23 } 24 25 /// 26 /// 判断key是否存储 27 /// 28 /// redis key 29 /// 30 public bool KeyExists(string key) 31 { 32 key = AddSysCustomKey(key); 33 return Do(db => db.KeyExists(key)); 34 } 35 36 /// 37 /// 重新命名key 38 /// 39 /// 就的redis key 40 /// 新的redis key 41 /// 42 public bool KeyRename(string key, string newKey) 43 { 44 key = AddSysCustomKey(key); 45 return Do(db => db.KeyRename(key, newKey)); 46 } 47 48 /// 49 /// 设置Key的时间 50 /// 51 /// redis key 52 /// 53 /// 54 public bool KeyExpire(string key, TimeSpan? expiry = default(TimeSpan?)) 55 { 56 key = AddSysCustomKey(key); 57 return Do(db => db.KeyExpire(key, expiry)); 58 } 59 60 #endregion key
发布和订阅
1 #region 发布订阅 2 3 ///4 /// Redis发布订阅 订阅 5 /// 6 /// 7 /// 8 public void Subscribe(string subChannel, Action handler = null) 9 { 10 ISubscriber sub = _conn.GetSubscriber(); 11 sub.Subscribe(subChannel, (channel, message) => 12 { 13 if (handler == null) 14 { 15 Console.WriteLine(subChannel + " 订阅收到消息:" + message); 16 } 17 else 18 { 19 handler(channel, message); 20 } 21 }); 22 } 23 24 /// 25 /// Redis发布订阅 发布 26 /// 27 /// 28 /// 29 /// 30 /// 31 public long Publish (string channel, T msg) 32 { 33 ISubscriber sub = _conn.GetSubscriber(); 34 return sub.Publish(channel, ConvertJson(msg)); 35 } 36 37 /// 38 /// Redis发布订阅 取消订阅 39 /// 40 /// 41 public void Unsubscribe(string channel) 42 { 43 ISubscriber sub = _conn.GetSubscriber(); 44 sub.Unsubscribe(channel); 45 } 46 47 /// 48 /// Redis发布订阅 取消全部订阅 49 /// 50 public void UnsubscribeAll() 51 { 52 ISubscriber sub = _conn.GetSubscriber(); 53 sub.UnsubscribeAll(); 54 } 55 56 #endregion 发布订阅
其他
1 #region 其他 2 3 public ITransaction CreateTransaction() 4 { 5 return GetDatabase().CreateTransaction(); 6 } 7 8 public IDatabase GetDatabase() 9 { 10 return _conn.GetDatabase(DbNum); 11 } 12 13 public IServer GetServer(string hostAndPort) 14 { 15 return _conn.GetServer(hostAndPort); 16 } 17 18 ///19 /// 设置前缀 20 /// 21 /// 22 public void SetSysCustomKey(string customKey) 23 { 24 CustomKey = customKey; 25 } 26 27 #endregion 其他
以上就是对StackExchange.Redis基本操作的通用封装,提供给大家学习参考,如果有哪里写错的,也希望能一起交流。
问题:
StackExchange.Redis没有提供Redis分布式锁的操作么?ServiceStack.Redis 提供了AcquireLock 的方法来操作,StackExchange.Redis 源码中只找到了LockTake的方法,并没有找到其他的方法了,如果有人使用过,还希望能提供下。
最后,附上源码地址:https://github.com/qq1206676756/RedisHelp