StackExchange.Redis通用封裝類分享,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 }
ConnectionMultiplexer幫助類
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 }
RedisHelper
其中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
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
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
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 有序集合
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
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