StackExchange.Redis通用封装类分享(转)
阅读目录
前两天朋友问我,有没有使用过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 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 /// <summary>
17 /// 单例获取
18 /// </summary>
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 /// <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 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<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 String
2
3 #region 同步方法
4
5 /// <summary>
6 /// 保存单个key value
7 /// </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 value
20 /// </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 /// 获取多个Key
58 /// </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 /// 为数字增长val
81 /// </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 /// 为数字减少val
93 /// </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 List
2
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的List
18 /// </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 Hash
2
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 /// 为数字增长val
79 /// </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 /// 为数字减少val
92 /// </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 key
2
3 /// <summary>
4 /// 删除单个key
5 /// </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通用封装类分享
前两天朋友问我,有没有使用过StackExchange.Redis,问我要个封装类,由于之前都是使用ServiceStack.Redis,由于ServiceStack.Redis v4版本后是收费版的 ...
- StackExchange.Redis 访问封装类
最近需要在C#中使用Redis,在Redis的官网找到了ServiceStack.Redis,最后在测试的时候发现这是个坑,4.0已上已经收费,后面只好找到3系列的最终版本,最后测试发现还是有BUG或 ...
- Windows下Redis缓存服务器的使用 .NET StackExchange.Redis Redis Desktop Manager
Redis缓存服务器是一款key/value数据库,读110000次/s,写81000次/s,因为是内存操作所以速度飞快,常见用法是存用户token.短信验证码等 官网显示Redis本身并没有Wind ...
- Windows下Redis缓存服务器的使用 .NET StackExchange.Redis Redis Desktop Manager 转发非原创
Windows下Redis缓存服务器的使用 .NET StackExchange.Redis Redis Desktop Manager Redis缓存服务器是一款key/value数据库,读11 ...
- [转]Windows下Redis缓存服务器的使用 .NET StackExchange.Redis Redis Desktop Manager
转自:http://www.cnblogs.com/oppoic/p/6165581.html Redis缓存服务器是一款key/value数据库,读110000次/s,写81000次/s,因为是内存 ...
- StackExchange.Redis实现Redis发布订阅
由于ServiceStack.Redis最新版已经收费,所以现在大家陆陆续续都换到StackExchange.Redis上了,关于StackExchange.Redis详细可以参看Github htt ...
- StackExchange.Redis 封装类
using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using ...
- StackExchange.Redis帮助类解决方案RedisRepository封装(基础配置)
本文版权归博客园和作者吴双本人共同所有,转载和爬虫,请注明原文地址.http://www.cnblogs.com/tdws/p/5815735.html 写在前面 这不是教程,分享而已,也欢迎园友们多 ...
- StackExchange.Redis客户端读写主从配置,以及哨兵配置。
今天简单分享一下StackExchange.Redis客户端中配置主从分离以及哨兵的配置. 关于哨兵如果有不了解的朋友,可以看我之前的一篇分享,当然主从复制文章也可以找到.http://www.cnb ...
随机推荐
- JS全屏漂浮广告、移入光标停止移动
点击这里查看效果 以下是代码: <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Ty ...
- div盒子垂直水平居中
div盒子,水平垂直居中. <!DOCTYPE html><html> <head> <meta charset="utf-8"> ...
- js(jquery)解决input元素的blur事件和其他非表单元素的click事件冲突的方法
HTML结构:很简单,就一个input,一个div,能说明问题就OK了: <input type="text" value="默认值"><br ...
- 天津政府应急系统之GIS一张图(arcgis api for flex)讲解(二)鹰眼模块
讲解GIS功能模块实现之前,先大概说一下flexviewer的核心配置文件config.xml,系统额GIS功能widget菜单布局.系统的样式.地图资源等等都是在这里配置的,这里对flexviewe ...
- IBM实习
来到北京,进入IBM实习已经好多天了,两个月的暑假,两个月夏日在这里度过了,并将在未来个一个月里面,仍将在这里走过,但是我却一无所成,现在仍然只在徘徊中游走,丹迪什么时候能真正懂得实习的难得可贵,懂得 ...
- Android—基于Socket与上传图片到客户端
最近项目中需要客户端和Socket互相传递数据时候需要相互传递图片所以做下总结以免以后忘记,也希望给大家带来帮助. 先上客户端的代码: 根据图片名称上传照相机中单个照片(此方法为自己封装) 参数所代表 ...
- Reporting Service 告警"w WARN: Thread pool pressure. Using current thread for a work item"
如果Reporting Service偶尔出现不可访问或访问出错情况,这种情况一般没有做监控的话,很难捕捉到.出现这种问题,最好检查Reporting Service的日志文件. 今天早上就遇到这样一 ...
- [AlwaysOn Availability Groups]SQL Server错误日志(AG)
SQL Server错误日志(AG) SQL Server错误日志会记录影响AG的时间,比如: 1.和Windows故障转移集群交互 2.可用副本的状态 3.可用数据的状态 4.AG endpoint ...
- easyui-datagrid连接数据库实现分页查询数据
一.利用MVC思想建立底层数据库: package com.hanqi.dao; import java.util.ArrayList; import java.util.List; import o ...
- 用python pickle库来存储数据对象
pickling有一个更常用的叫法是serialization,它是指把python对象转化成字节流byte stream, unpickling就是把byte stream转换成对象.python的 ...