StackExchange.Redis通用封装类分享(转)
阅读目录
- ConnectionMultiplexer 封装
- RedisHelper 通用操作类封
- String类型的封装
- List类型的封装
- Hash类型的封装
- SortedSet 类型的封装
- key的管理
- 发布和订阅
- 其他
前两天朋友问我,有没有使用过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 /// <summary>2 /// ConnectionMultiplexer对象管理帮助类3 /// </summary>4 public static class RedisConnectionHelp5 {6 //系统自定义Key前缀7 public static readonly string SysCustomKey = ConfigurationManager.AppSettings["redisKey"] ?? "";8 9 //"127.0.0.1:6379,allowadmin=true10 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 /// <summary>17 /// 单例获取18 /// </summary>19 public static ConnectionMultiplexer Instance20 {21 get22 {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 /// <summary>38 /// 缓存获取39 /// </summary>40 /// <param name="connectionString"></param>41 /// <returns></returns>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 /// <summary>70 /// 配置更改时71 /// </summary>72 /// <param name="sender"></param>73 /// <param name="e"></param>74 private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)75 {76 Console.WriteLine("Configuration changed: " + e.EndPoint);77 }78 79 /// <summary>80 /// 发生错误时81 /// </summary>82 /// <param name="sender"></param>83 /// <param name="e"></param>84 private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)85 {86 Console.WriteLine("ErrorMessage: " + e.Message);87 }88 89 /// <summary>90 /// 重新建立连接之前的错误91 /// </summary>92 /// <param name="sender"></param>93 /// <param name="e"></param>94 private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)95 {96 Console.WriteLine("ConnectionRestored: " + e.EndPoint);97 }98 99 /// <summary>
100 /// 连接失败 , 如果重新连接成功你将不会收到这个通知
101 /// </summary>
102 /// <param name="sender"></param>
103 /// <param name="e"></param>
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 /// <summary>
110 /// 更改集群
111 /// </summary>
112 /// <param name="sender"></param>
113 /// <param name="e"></param>
114 private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
115 {
116 Console.WriteLine("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);
117 }
118
119 /// <summary>
120 /// redis类库错误
121 /// </summary>
122 /// <param name="sender"></param>
123 /// <param name="e"></param>
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 RedisHelper2 {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<T>(Func<IDatabase, T> func)
32 {
33 var database = _conn.GetDatabase(DbNum);
34 return func(database);
35 }
36
37 private string ConvertJson<T>(T value)
38 {
39 string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value);
40 return result;
41 }
42
43 private T ConvertObj<T>(RedisValue value)
44 {
45 return JsonConvert.DeserializeObject<T>(value);
46 }
47
48 private List<T> ConvetList<T>(RedisValue[] values)
49 {
50 List<T> result = new List<T>();
51 foreach (var item in values)
52 {
53 var model = ConvertObj<T>(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 String2 3 #region 同步方法4 5 /// <summary>6 /// 保存单个key value7 /// </summary>8 /// <param name="key">Redis Key</param>9 /// <param name="value">保存的值</param>10 /// <param name="expiry">过期时间</param>11 /// <returns></returns>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 /// <summary>19 /// 保存多个key value20 /// </summary>21 /// <param name="keyValues">键值对</param>22 /// <returns></returns>23 public bool StringSet(List<KeyValuePair<RedisKey, RedisValue>> keyValues)24 {25 List<KeyValuePair<RedisKey, RedisValue>> newkeyValues =26 keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList();27 return Do(db => db.StringSet(newkeyValues.ToArray()));28 }29 30 /// <summary>31 /// 保存一个对象32 /// </summary>33 /// <typeparam name="T"></typeparam>34 /// <param name="key"></param>35 /// <param name="obj"></param>36 /// <param name="expiry"></param>37 /// <returns></returns>38 public bool StringSet<T>(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 /// <summary>46 /// 获取单个key的值47 /// </summary>48 /// <param name="key">Redis Key</param>49 /// <returns></returns>50 public string StringGet(string key)51 {52 key = AddSysCustomKey(key);53 return Do(db => db.StringGet(key));54 }55 56 /// <summary>57 /// 获取多个Key58 /// </summary>59 /// <param name="listKey">Redis Key集合</param>60 /// <returns></returns>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 /// <summary>68 /// 获取一个key的对象69 /// </summary>70 /// <typeparam name="T"></typeparam>71 /// <param name="key"></param>72 /// <returns></returns>73 public T StringGet<T>(string key)74 {75 key = AddSysCustomKey(key);76 return Do(db => ConvertObj<T>(db.StringGet(key)));77 }78 79 /// <summary>80 /// 为数字增长val81 /// </summary>82 /// <param name="key"></param>83 /// <param name="val">可以为负</param>84 /// <returns>增长后的值</returns>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 /// <summary>92 /// 为数字减少val93 /// </summary>94 /// <param name="key"></param>95 /// <param name="val">可以为负</param>96 /// <returns>减少后的值</returns>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 /// <summary>
108 /// 保存单个key value
109 /// </summary>
110 /// <param name="key">Redis Key</param>
111 /// <param name="value">保存的值</param>
112 /// <param name="expiry">过期时间</param>
113 /// <returns></returns>
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 /// <summary>
121 /// 保存多个key value
122 /// </summary>
123 /// <param name="keyValues">键值对</param>
124 /// <returns></returns>
125 public async Task<bool> StringSetAsync(List<KeyValuePair<RedisKey, RedisValue>> keyValues)
126 {
127 List<KeyValuePair<RedisKey, RedisValue>> newkeyValues =
128 keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList();
129 return await Do(db => db.StringSetAsync(newkeyValues.ToArray()));
130 }
131
132 /// <summary>
133 /// 保存一个对象
134 /// </summary>
135 /// <typeparam name="T"></typeparam>
136 /// <param name="key"></param>
137 /// <param name="obj"></param>
138 /// <param name="expiry"></param>
139 /// <returns></returns>
140 public async Task<bool> StringSetAsync<T>(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 /// <summary>
148 /// 获取单个key的值
149 /// </summary>
150 /// <param name="key">Redis Key</param>
151 /// <returns></returns>
152 public async Task<string> StringGetAsync(string key)
153 {
154 key = AddSysCustomKey(key);
155 return await Do(db => db.StringGetAsync(key));
156 }
157
158 /// <summary>
159 /// 获取多个Key
160 /// </summary>
161 /// <param name="listKey">Redis Key集合</param>
162 /// <returns></returns>
163 public async Task<RedisValue[]> 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 /// <summary>
170 /// 获取一个key的对象
171 /// </summary>
172 /// <typeparam name="T"></typeparam>
173 /// <param name="key"></param>
174 /// <returns></returns>
175 public async Task<T> StringGetAsync<T>(string key)
176 {
177 key = AddSysCustomKey(key);
178 string result = await Do(db => db.StringGetAsync(key));
179 return ConvertObj<T>(result);
180 }
181
182 /// <summary>
183 /// 为数字增长val
184 /// </summary>
185 /// <param name="key"></param>
186 /// <param name="val">可以为负</param>
187 /// <returns>增长后的值</returns>
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 /// <summary>
195 /// 为数字减少val
196 /// </summary>
197 /// <param name="key"></param>
198 /// <param name="val">可以为负</param>
199 /// <returns>减少后的值</returns>
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 List2 3 #region 同步方法4 5 /// <summary>6 /// 移除指定ListId的内部List的值7 /// </summary>8 /// <param name="key"></param>9 /// <param name="value"></param>10 public void ListRemove<T>(string key, T value)11 {12 key = AddSysCustomKey(key);13 Do(db => db.ListRemove(key, ConvertJson(value)));14 }15 16 /// <summary>17 /// 获取指定key的List18 /// </summary>19 /// <param name="key"></param>20 /// <returns></returns>21 public List<T> ListRange<T>(string key)22 {23 key = AddSysCustomKey(key);24 return Do(redis =>25 {26 var values = redis.ListRange(key);27 return ConvetList<T>(values);28 });29 }30 31 /// <summary>32 /// 入队33 /// </summary>34 /// <param name="key"></param>35 /// <param name="value"></param>36 public void ListRightPush<T>(string key, T value)37 {38 key = AddSysCustomKey(key);39 Do(db => db.ListRightPush(key, ConvertJson(value)));40 }41 42 /// <summary>43 /// 出队44 /// </summary>45 /// <typeparam name="T"></typeparam>46 /// <param name="key"></param>47 /// <returns></returns>48 public T ListRightPop<T>(string key)49 {50 key = AddSysCustomKey(key);51 return Do(db =>52 {53 var value = db.ListRightPop(key);54 return ConvertObj<T>(value);55 });56 }57 58 /// <summary>59 /// 入栈60 /// </summary>61 /// <typeparam name="T"></typeparam>62 /// <param name="key"></param>63 /// <param name="value"></param>64 public void ListLeftPush<T>(string key, T value)65 {66 key = AddSysCustomKey(key);67 Do(db => db.ListLeftPush(key, ConvertJson(value)));68 }69 70 /// <summary>71 /// 出栈72 /// </summary>73 /// <typeparam name="T"></typeparam>74 /// <param name="key"></param>75 /// <returns></returns>76 public T ListLeftPop<T>(string key)77 {78 key = AddSysCustomKey(key);79 return Do(db =>80 {81 var value = db.ListLeftPop(key);82 return ConvertObj<T>(value);83 });84 }85 86 /// <summary>87 /// 获取集合中的数量88 /// </summary>89 /// <param name="key"></param>90 /// <returns></returns>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 /// <summary>
102 /// 移除指定ListId的内部List的值
103 /// </summary>
104 /// <param name="key"></param>
105 /// <param name="value"></param>
106 public async Task<long> ListRemoveAsync<T>(string key, T value)
107 {
108 key = AddSysCustomKey(key);
109 return await Do(db => db.ListRemoveAsync(key, ConvertJson(value)));
110 }
111
112 /// <summary>
113 /// 获取指定key的List
114 /// </summary>
115 /// <param name="key"></param>
116 /// <returns></returns>
117 public async Task<List<T>> ListRangeAsync<T>(string key)
118 {
119 key = AddSysCustomKey(key);
120 var values = await Do(redis => redis.ListRangeAsync(key));
121 return ConvetList<T>(values);
122 }
123
124 /// <summary>
125 /// 入队
126 /// </summary>
127 /// <param name="key"></param>
128 /// <param name="value"></param>
129 public async Task<long> ListRightPushAsync<T>(string key, T value)
130 {
131 key = AddSysCustomKey(key);
132 return await Do(db => db.ListRightPushAsync(key, ConvertJson(value)));
133 }
134
135 /// <summary>
136 /// 出队
137 /// </summary>
138 /// <typeparam name="T"></typeparam>
139 /// <param name="key"></param>
140 /// <returns></returns>
141 public async Task<T> ListRightPopAsync<T>(string key)
142 {
143 key = AddSysCustomKey(key);
144 var value = await Do(db => db.ListRightPopAsync(key));
145 return ConvertObj<T>(value);
146 }
147
148 /// <summary>
149 /// 入栈
150 /// </summary>
151 /// <typeparam name="T"></typeparam>
152 /// <param name="key"></param>
153 /// <param name="value"></param>
154 public async Task<long> ListLeftPushAsync<T>(string key, T value)
155 {
156 key = AddSysCustomKey(key);
157 return await Do(db => db.ListLeftPushAsync(key, ConvertJson(value)));
158 }
159
160 /// <summary>
161 /// 出栈
162 /// </summary>
163 /// <typeparam name="T"></typeparam>
164 /// <param name="key"></param>
165 /// <returns></returns>
166 public async Task<T> ListLeftPopAsync<T>(string key)
167 {
168 key = AddSysCustomKey(key);
169 var value = await Do(db => db.ListLeftPopAsync(key));
170 return ConvertObj<T>(value);
171 }
172
173 /// <summary>
174 /// 获取集合中的数量
175 /// </summary>
176 /// <param name="key"></param>
177 /// <returns></returns>
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 Hash2 3 #region 同步方法4 5 /// <summary>6 /// 判断某个数据是否已经被缓存7 /// </summary>8 /// <param name="key"></param>9 /// <param name="dataKey"></param>10 /// <returns></returns>11 public bool HashExists(string key, string dataKey)12 {13 key = AddSysCustomKey(key);14 return Do(db => db.HashExists(key, dataKey));15 }16 17 /// <summary>18 /// 存储数据到hash表19 /// </summary>20 /// <typeparam name="T"></typeparam>21 /// <param name="key"></param>22 /// <param name="dataKey"></param>23 /// <param name="t"></param>24 /// <returns></returns>25 public bool HashSet<T>(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 /// <summary>36 /// 移除hash中的某值37 /// </summary>38 /// <param name="key"></param>39 /// <param name="dataKey"></param>40 /// <returns></returns>41 public bool HashDelete(string key, string dataKey)42 {43 key = AddSysCustomKey(key);44 return Do(db => db.HashDelete(key, dataKey));45 }46 47 /// <summary>48 /// 移除hash中的多个值49 /// </summary>50 /// <param name="key"></param>51 /// <param name="dataKeys"></param>52 /// <returns></returns>53 public long HashDelete(string key, List<RedisValue> dataKeys)54 {55 key = AddSysCustomKey(key);56 //List<RedisValue> dataKeys1 = new List<RedisValue>() {"1","2"};57 return Do(db => db.HashDelete(key, dataKeys.ToArray()));58 }59 60 /// <summary>61 /// 从hash表获取数据62 /// </summary>63 /// <typeparam name="T"></typeparam>64 /// <param name="key"></param>65 /// <param name="dataKey"></param>66 /// <returns></returns>67 public T HashGet<T>(string key, string dataKey)68 {69 key = AddSysCustomKey(key);70 return Do(db =>71 {72 string value = db.HashGet(key, dataKey);73 return ConvertObj<T>(value);74 });75 }76 77 /// <summary>78 /// 为数字增长val79 /// </summary>80 /// <param name="key"></param>81 /// <param name="dataKey"></param>82 /// <param name="val">可以为负</param>83 /// <returns>增长后的值</returns>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 /// <summary>91 /// 为数字减少val92 /// </summary>93 /// <param name="key"></param>94 /// <param name="dataKey"></param>95 /// <param name="val">可以为负</param>96 /// <returns>减少后的值</returns>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 /// <summary>
104 /// 获取hashkey所有Redis key
105 /// </summary>
106 /// <typeparam name="T"></typeparam>
107 /// <param name="key"></param>
108 /// <returns></returns>
109 public List<T> HashKeys<T>(string key)
110 {
111 key = AddSysCustomKey(key);
112 return Do(db =>
113 {
114 RedisValue[] values = db.HashKeys(key);
115 return ConvetList<T>(values);
116 });
117 }
118
119 #endregion 同步方法
120
121 #region 异步方法
122
123 /// <summary>
124 /// 判断某个数据是否已经被缓存
125 /// </summary>
126 /// <param name="key"></param>
127 /// <param name="dataKey"></param>
128 /// <returns></returns>
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 /// <summary>
136 /// 存储数据到hash表
137 /// </summary>
138 /// <typeparam name="T"></typeparam>
139 /// <param name="key"></param>
140 /// <param name="dataKey"></param>
141 /// <param name="t"></param>
142 /// <returns></returns>
143 public async Task<bool> HashSetAsync<T>(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 /// <summary>
154 /// 移除hash中的某值
155 /// </summary>
156 /// <param name="key"></param>
157 /// <param name="dataKey"></param>
158 /// <returns></returns>
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 /// <summary>
166 /// 移除hash中的多个值
167 /// </summary>
168 /// <param name="key"></param>
169 /// <param name="dataKeys"></param>
170 /// <returns></returns>
171 public async Task<long> HashDeleteAsync(string key, List<RedisValue> dataKeys)
172 {
173 key = AddSysCustomKey(key);
174 //List<RedisValue> dataKeys1 = new List<RedisValue>() {"1","2"};
175 return await Do(db => db.HashDeleteAsync(key, dataKeys.ToArray()));
176 }
177
178 /// <summary>
179 /// 从hash表获取数据
180 /// </summary>
181 /// <typeparam name="T"></typeparam>
182 /// <param name="key"></param>
183 /// <param name="dataKey"></param>
184 /// <returns></returns>
185 public async Task<T> HashGeAsync<T>(string key, string dataKey)
186 {
187 key = AddSysCustomKey(key);
188 string value = await Do(db => db.HashGetAsync(key, dataKey));
189 return ConvertObj<T>(value);
190 }
191
192 /// <summary>
193 /// 为数字增长val
194 /// </summary>
195 /// <param name="key"></param>
196 /// <param name="dataKey"></param>
197 /// <param name="val">可以为负</param>
198 /// <returns>增长后的值</returns>
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 /// <summary>
206 /// 为数字减少val
207 /// </summary>
208 /// <param name="key"></param>
209 /// <param name="dataKey"></param>
210 /// <param name="val">可以为负</param>
211 /// <returns>减少后的值</returns>
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 /// <summary>
219 /// 获取hashkey所有Redis key
220 /// </summary>
221 /// <typeparam name="T"></typeparam>
222 /// <param name="key"></param>
223 /// <returns></returns>
224 public async Task<List<T>> HashKeysAsync<T>(string key)
225 {
226 key = AddSysCustomKey(key);
227 RedisValue[] values = await Do(db => db.HashKeysAsync(key));
228 return ConvetList<T>(values);
229 }
230
231 #endregion 异步方法
232
233 #endregion Hash
SortedSet 类型的封装
1 #region SortedSet 有序集合2 3 #region 同步方法4 5 /// <summary>6 /// 添加7 /// </summary>8 /// <param name="key"></param>9 /// <param name="value"></param>10 /// <param name="score"></param>11 public bool SortedSetAdd<T>(string key, T value, double score)12 {13 key = AddSysCustomKey(key);14 return Do(redis => redis.SortedSetAdd(key, ConvertJson<T>(value), score));15 }16 17 /// <summary>18 /// 删除19 /// </summary>20 /// <param name="key"></param>21 /// <param name="value"></param>22 public bool SortedSetRemove<T>(string key, T value)23 {24 key = AddSysCustomKey(key);25 return Do(redis => redis.SortedSetRemove(key, ConvertJson(value)));26 }27 28 /// <summary>29 /// 获取全部30 /// </summary>31 /// <param name="key"></param>32 /// <returns></returns>33 public List<T> SortedSetRangeByRank<T>(string key)34 {35 key = AddSysCustomKey(key);36 return Do(redis =>37 {38 var values = redis.SortedSetRangeByRank(key);39 return ConvetList<T>(values);40 });41 }42 43 /// <summary>44 /// 获取集合中的数量45 /// </summary>46 /// <param name="key"></param>47 /// <returns></returns>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 /// <summary>59 /// 添加60 /// </summary>61 /// <param name="key"></param>62 /// <param name="value"></param>63 /// <param name="score"></param>64 public async Task<bool> SortedSetAddAsync<T>(string key, T value, double score)65 {66 key = AddSysCustomKey(key);67 return await Do(redis => redis.SortedSetAddAsync(key, ConvertJson<T>(value), score));68 }69 70 /// <summary>71 /// 删除72 /// </summary>73 /// <param name="key"></param>74 /// <param name="value"></param>75 public async Task<bool> SortedSetRemoveAsync<T>(string key, T value)76 {77 key = AddSysCustomKey(key);78 return await Do(redis => redis.SortedSetRemoveAsync(key, ConvertJson(value)));79 }80 81 /// <summary>82 /// 获取全部83 /// </summary>84 /// <param name="key"></param>85 /// <returns></returns>86 public async Task<List<T>> SortedSetRangeByRankAsync<T>(string key)87 {88 key = AddSysCustomKey(key);89 var values = await Do(redis => redis.SortedSetRangeByRankAsync(key));90 return ConvetList<T>(values);91 }92 93 /// <summary>94 /// 获取集合中的数量95 /// </summary>96 /// <param name="key"></param>97 /// <returns></returns>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 key2 3 /// <summary>4 /// 删除单个key5 /// </summary>6 /// <param name="key">redis key</param>7 /// <returns>是否删除成功</returns>8 public bool KeyDelete(string key)9 {
10 key = AddSysCustomKey(key);
11 return Do(db => db.KeyDelete(key));
12 }
13
14 /// <summary>
15 /// 删除多个key
16 /// </summary>
17 /// <param name="keys">rediskey</param>
18 /// <returns>成功删除的个数</returns>
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 /// <summary>
26 /// 判断key是否存储
27 /// </summary>
28 /// <param name="key">redis key</param>
29 /// <returns></returns>
30 public bool KeyExists(string key)
31 {
32 key = AddSysCustomKey(key);
33 return Do(db => db.KeyExists(key));
34 }
35
36 /// <summary>
37 /// 重新命名key
38 /// </summary>
39 /// <param name="key">就的redis key</param>
40 /// <param name="newKey">新的redis key</param>
41 /// <returns></returns>
42 public bool KeyRename(string key, string newKey)
43 {
44 key = AddSysCustomKey(key);
45 return Do(db => db.KeyRename(key, newKey));
46 }
47
48 /// <summary>
49 /// 设置Key的时间
50 /// </summary>
51 /// <param name="key">redis key</param>
52 /// <param name="expiry"></param>
53 /// <returns></returns>
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 /// <summary>4 /// Redis发布订阅 订阅5 /// </summary>6 /// <param name="subChannel"></param>7 /// <param name="handler"></param>8 public void Subscribe(string subChannel, Action<RedisChannel, RedisValue> 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 /// <summary>
25 /// Redis发布订阅 发布
26 /// </summary>
27 /// <typeparam name="T"></typeparam>
28 /// <param name="channel"></param>
29 /// <param name="msg"></param>
30 /// <returns></returns>
31 public long Publish<T>(string channel, T msg)
32 {
33 ISubscriber sub = _conn.GetSubscriber();
34 return sub.Publish(channel, ConvertJson(msg));
35 }
36
37 /// <summary>
38 /// Redis发布订阅 取消订阅
39 /// </summary>
40 /// <param name="channel"></param>
41 public void Unsubscribe(string channel)
42 {
43 ISubscriber sub = _conn.GetSubscriber();
44 sub.Unsubscribe(channel);
45 }
46
47 /// <summary>
48 /// Redis发布订阅 取消全部订阅
49 /// </summary>
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 /// <summary>
19 /// 设置前缀
20 /// </summary>
21 /// <param name="customKey"></param>
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
http://www.cnblogs.com/qtqq/p/5951201.html
StackExchange.Redis通用封装类分享(转)相关推荐
- StackExchange.Redis 访问封装类
最近需要在C#中使用Redis,在Redis的官网找到了ServiceStack.Redis,最后在测试的时候发现这是个坑,4.0已上已经收费,后面只好找到3系列的最终版本,最后测试发现还是有BUG或 ...
- StackExchange.Redis客户端读写主从配置,以及哨兵配置
今天简单分享一下StackExchange.Redis客户端中配置主从分离以及哨兵的配置. 关于哨兵如果有不了解的朋友,可以看我之前的一篇分享,当然主从复制文章也可以找到.http://www.cnb ...
- StackExchange.Redis 官方文档(二) Configuration
配置 有多种方式可以配置redis,StackExchange.Redis提供了一个丰富的配置模型,在执行Connect (or ConnectAsync) 时被调用: var conn = Conn ...
- StackExchange.Redis 命令扩展
StackExchange.Redis 命令扩展 Intro 在之前的文章中有简单介绍过 StackExchange.Redis 直接调用 Redis 命令来实现调用 Stream 的根据消息 Id ...
- StackExchange.Redis性能调优
编者:.net core redis 驱动推荐,为什么不使用 StackExchange.Redis 引起了很大的反响,大家反应过度,其实StackExchange.Redis 2.0已经从重构了异步 ...
- Redis集群~StackExchange.redis连接Sentinel服务器并订阅相关事件
对于redis-sentinel我在之前的文章中Redis集群~StackExchange.redis连接Twemproxy代理服务器 已经说过,它是一个仲裁者,当主master挂了后,它将在所有sl ...
- Redis集群~StackExchange.redis连接Twemproxy代理服务器
本文是Redis集群系列的一篇文章,主要介绍使用StackExchange.Redis进行Twemproxy(文中简称TW)代理服务的连接过程,事务上,对于TW来说,我们需要理解一下它的物理架构,它类 ...
- .NET Core StackExchange.Redis使用方法
一.引入StackExchange.Redis 打开NuGet, 点击"浏览"页面,输入"StackExchange.Redis",进行安装. 二.创建Redi ...
- (三)Redis for StackExchange.Redis
目录 (一)Redis for Windows正确打开方式 (二)Redis for 阿里云公网连接 (三)Redis for StackExchange.Redis StackExchange.Re ...
最新文章
- Debian7.0中Fcitx输入法无可用前端问题解决
- java map操作_Java 8 中的 Map 骚操作,学习下!
- [YTU]_2907(类重载实现矩阵加法)
- Maven2的配置文件settings.xml
- python list操作复杂度
- DBASK问答集萃第二期
- 一个成功的Jsp程序员该怎样学习JSP呢?
- Oracle DataBase单实例使用ASM案例(2)--Oracle 11g之环境准备
- Intellij如何把JAR包加入到项目运行环境中
- 云计算项目实战——系统API模块
- VMware16安装Redhat7 图文教程
- java毕业设计成品源码网站基于SpringBoot旅游信息管理系统
- 开源ext2read代码走读之--“\\\\.\\PhysicalDrive0”意义?
- AGND和GND_SIGNAL之间的隔离_PCB
- 切换计算机管理员身份,管理员身份运行,教您如何设置以管理员身份运行程序...
- 医疗病案首页网上直报编码汇总
- c语言间接级别不同_间接寻址不同问题?求解决!
- 谷歌浏览器插件自动点击程序
- 禁用计算机硬盘,怎么禁止电脑开机就自动检测硬盘
- 奥迪A6(C5)停车加热(驻车暖风)01406故障
热门文章
- C++尽量以const,enum,inline替换#define
- C++ deque方法
- QT的QActionGroup类的使用
- 经典C语言程序100例之八零
- C++STL容器大全
- C语言编程如何快速注释?
- maven web项目导入sts_Spring Boot2 系列教程(二)创建 Spring Boot 项目的三种方式
- 04_05_06:设置线型风格(设置线型风格)、区域着色 (Shading Regions)、设置Spines
- IntelliJ Idea取消Colud not autowire.No
- Spark-Sql整合hive,在spark-sql命令和spark-shell命令下执行sql命令和整合调用hive