C#-Redis帮助类(.Net Framework)

  1. Redis简要介绍

  引用百度百科的话,就是:Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value NoSQL数据库,并提供多种语言的API。

  Redis的主要使用场景:缓存、消息队列、频繁读写等,还有很多等等,这个可以随处搜到;Redis的优势就是读写数据性能高,支持数据类型丰富,所有操作都是原子性,成功或者不成功,现在还支持发布订阅等特性。

  2. .Net Framework操作Redis

  创建新项目等等其他的我就不截图了,我使用的是VS2019专业版, .Net Framework 4.7.2,都行,这个都支持,无非可能是类库更新导致有些最新功能你不能用。

  技术图片

 

  看下项目的一个结构,当前选中的为启动项目,控制台应用程序,另外两个是用到的自定义类库,RedisHelp为自定义的Redis帮助类库,用到的Nuget包为StackExchange.Redis2.1.30,LogManager是一个写日志的帮助类;

  技术图片

 

 

  ① 配置文件配置,RedisTest项目展开,打开App.config,添加Redis服务的IP和端口,<add name="RedisExchangeHosts" connectionString="127.0.0.1:6379,allowadmin=true" />

  技术图片

  ② ConnectionMultiplexer封装

  ConnectionMultiplexer对象是StackExchange.Redis最中枢的对象。这个类的实例需要被整个应用程序域共享和重用的,所以不需要在每个操作中不停的创建该对象的实例,一般都是使用单例来创建和存放这个对象,提高程序运行的效率,这个在官网上也有说明的。

技术图片
技术图片

 1 /// <summary> 2 /// ConnectionMultiplexer对象管理帮助类 3 /// </summary> 4 public static class RedisConnectionHelp 5  { 6 #region 属性 7  8 /// <summary> 9 /// 系统自定义Key前缀 10 /// </summary> 11 public static readonly string SysCustomKey = ConfigurationManager.AppSettings["redisKey"] ?? ""; 12  13 /// <summary> 14 /// Redis链接字符串 15 /// </summary> 16 private static readonly string RedisConnectionString = ConfigurationManager.ConnectionStrings["RedisExchangeHosts"].ConnectionString; 17  18 /// <summary> 19 /// 链接缓存池 20 /// </summary> 21 private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string, ConnectionMultiplexer>(); 22  23 #endregion 24  25 #region 单例和构造 26  27 /// <summary> 28 /// 29 /// </summary> 30 private static readonly object Locker = new object(); 31  32 /// <summary> 33 /// 单例 34 /// </summary> 35 private static ConnectionMultiplexer _instance; 36  37  38 /// <summary> 39 /// 单例获取 40 /// </summary> 41 public static ConnectionMultiplexer Instance 42  { 43 get 44  { 45 if (_instance == null) 46  { 47 lock (Locker) 48  { 49 if (_instance == null || !_instance.IsConnected) 50  { 51 _instance = GetManager(); 52  } 53  } 54  } 55 return _instance; 56  } 57  } 58  59 /// <summary> 60 /// 缓存获取 61 /// </summary> 62 /// <param name="connectionString"></param> 63 /// <returns></returns> 64 public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString) 65  { 66 if (!ConnectionCache.ContainsKey(connectionString)) 67  { 68 ConnectionCache[connectionString] = GetManager(connectionString); 69  } 70 return ConnectionCache[connectionString]; 71  } 72  73 /// <summary> 74 /// 获取链接 75 /// </summary> 76 /// <param name="connectionString"></param> 77 /// <returns></returns> 78 private static ConnectionMultiplexer GetManager(string connectionString = null) 79  { 80 connectionString = connectionString ?? RedisConnectionString; 81 var connect = ConnectionMultiplexer.Connect(connectionString); 82  83 //注册如下事件 84 connect.ConnectionFailed += MuxerConnectionFailed; 85 connect.ConnectionRestored += MuxerConnectionRestored; 86 connect.ErrorMessage += MuxerErrorMessage; 87 connect.ConfigurationChanged += MuxerConfigurationChanged; 88 connect.HashSlotMoved += MuxerHashSlotMoved; 89 connect.InternalError += MuxerInternalError; 90  91 return connect; 92  } 93  94 #endregion 95  96 #region 事件 97  98 /// <summary> 99 /// 配置更改时100 /// </summary>101 /// <param name="sender"></param>102 /// <param name="e"></param>103 private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)104  {105 Console.WriteLine("Configuration changed: " + e.EndPoint);106  }107 108 /// <summary>109 /// 发生错误时110 /// </summary>111 /// <param name="sender"></param>112 /// <param name="e"></param>113 private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)114  {115 Console.WriteLine("ErrorMessage: " + e.Message);116  }117 118 /// <summary>119 /// 重新建立连接之前的错误120 /// </summary>121 /// <param name="sender"></param>122 /// <param name="e"></param>123 private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)124  {125 Console.WriteLine("ConnectionRestored: " + e.EndPoint);126  }127 128 /// <summary>129 /// 连接失败 , 如果重新连接成功你将不会收到这个通知130 /// </summary>131 /// <param name="sender"></param>132 /// <param name="e"></param>133 private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)134  {135 Console.WriteLine("重新连接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message)));136  }137 138 /// <summary>139 /// 更改集群140 /// </summary>141 /// <param name="sender"></param>142 /// <param name="e"></param>143 private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)144  {145 Console.WriteLine("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);146  }147 148 /// <summary>149 /// redis类库错误150 /// </summary>151 /// <param name="sender"></param>152 /// <param name="e"></param>153 private static void MuxerInternalError(object sender, InternalErrorEventArgs e)154  {155 Console.WriteLine("InternalError:Message" + e.Exception.Message);156  }157 158 #endregion 事件159 }

View Code

 

 

 

 

   ③ RedisHelper通用操作类封装

技术图片
技术图片

 1 /// <summary> 2 /// Redis操作类 3 /// </summary> 4 public class RedisHelper 5  { 6 #region 属性 7  8 /// <summary> 9 /// DB库 10 /// </summary> 11 private int DbNum { get; } 12  13 /// <summary> 14 /// Redis链接 15 /// </summary> 16 private readonly ConnectionMultiplexer _conn; 17  18 /// <summary> 19 /// 前缀 20 /// </summary> 21 public string CustomKey; 22  23 #endregion 24  25 #region 构造函数 26  27 /// <summary> 28 /// 默认构造 29 /// </summary> 30 /// <param name="dbNum">DB索引</param> 31 public RedisHelper(int dbNum = 0) 32 : this(dbNum, null) 33  { 34  } 35  36 /// <summary> 37 /// 构造 38 /// </summary> 39 /// <param name="dbNum"></param> 40 /// <param name="readWriteHosts"></param> 41 public RedisHelper(int dbNum, string readWriteHosts) 42  { 43 DbNum = dbNum; 44 _conn = 45 string.IsNullOrWhiteSpace(readWriteHosts) ? 46  RedisConnectionHelp.Instance : 47  RedisConnectionHelp.GetConnectionMultiplexer(readWriteHosts); 48  } 49  50 #endregion 构造函数 51  52 #region String 53  54 #region 同步方法 55  56 /// <summary> 57 /// 保存单个key value 58 /// </summary> 59 /// <param name="key">Redis Key</param> 60 /// <param name="value">保存的值</param> 61 /// <param name="expiry">过期时间</param> 62 /// <returns></returns> 63 public bool StringSet(string key, string value, TimeSpan? expiry = default(TimeSpan?)) 64  { 65 key = AddSysCustomKey(key); 66 return Do(db => db.StringSet(key, value, expiry)); 67  } 68  69 /// <summary> 70 /// 保存多个key value 71 /// </summary> 72 /// <param name="keyValues">键值对</param> 73 /// <returns></returns> 74 public bool StringSet(List<KeyValuePair<RedisKey, RedisValue>> keyValues) 75  { 76 List<KeyValuePair<RedisKey, RedisValue>> newkeyValues = 77 keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList(); 78 return Do(db => db.StringSet(newkeyValues.ToArray())); 79  } 80  81 /// <summary> 82 /// 保存一个对象 83 /// </summary> 84 /// <typeparam name="T"></typeparam> 85 /// <param name="key"></param> 86 /// <param name="obj"></param> 87 /// <param name="expiry"></param> 88 /// <returns></returns> 89 public bool StringSet<T>(string key, T obj, TimeSpan? expiry = default(TimeSpan?)) 90  { 91 key = AddSysCustomKey(key); 92 string json = ConvertJson(obj); 93 return Do(db => db.StringSet(key, json, expiry)); 94  } 95  96 /// <summary> 97 /// 获取单个key的值 98 /// </summary> 99 /// <param name="key">Redis Key</param> 100 /// <returns></returns> 101 public string StringGet(string key) 102  { 103 key = AddSysCustomKey(key); 104 return Do(db => db.StringGet(key)); 105  } 106  107 /// <summary> 108 /// 获取多个Key 109 /// </summary> 110 /// <param name="listKey">Redis Key集合</param> 111 /// <returns></returns> 112 public RedisValue[] StringGet(List<string> listKey) 113  { 114 List<string> newKeys = listKey.Select(AddSysCustomKey).ToList(); 115 return Do(db => db.StringGet(ConvertRedisKeys(newKeys))); 116  } 117  118 /// <summary> 119 /// 获取一个key的对象 120 /// </summary> 121 /// <typeparam name="T"></typeparam> 122 /// <param name="key"></param> 123 /// <returns></returns> 124 public T StringGet<T>(string key) 125  { 126 key = AddSysCustomKey(key); 127 return Do(db => ConvertObj<T>(db.StringGet(key))); 128  } 129  130 /// <summary> 131 /// 为数字增长val 132 /// </summary> 133 /// <param name="key"></param> 134 /// <param name="val">可以为负</param> 135 /// <returns>增长后的值</returns> 136 public double StringIncrement(string key, double val = 1) 137  { 138 key = AddSysCustomKey(key); 139 return Do(db => db.StringIncrement(key, val)); 140  } 141  142 /// <summary> 143 /// 为数字减少val 144 /// </summary> 145 /// <param name="key"></param> 146 /// <param name="val">可以为负</param> 147 /// <returns>减少后的值</returns> 148 public double StringDecrement(string key, double val = 1) 149  { 150 key = AddSysCustomKey(key); 151 return Do(db => db.StringDecrement(key, val)); 152  } 153  154 #endregion 同步方法 155  156 #region 异步方法 157  158 /// <summary> 159 /// 保存单个key value 160 /// </summary> 161 /// <param name="key">Redis Key</param> 162 /// <param name="value">保存的值</param> 163 /// <param name="expiry">过期时间</param> 164 /// <returns></returns> 165 public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = default(TimeSpan?)) 166  { 167 key = AddSysCustomKey(key); 168 return await Do(db => db.StringSetAsync(key, value, expiry)); 169  } 170  171 /// <summary> 172 /// 保存多个key value 173 /// </summary> 174 /// <param name="keyValues">键值对</param> 175 /// <returns></returns> 176 public async Task<bool> StringSetAsync(List<KeyValuePair<RedisKey, RedisValue>> keyValues) 177  { 178 List<KeyValuePair<RedisKey, RedisValue>> newkeyValues = 179 keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList(); 180 return await Do(db => db.StringSetAsync(newkeyValues.ToArray())); 181  } 182  183 /// <summary> 184 /// 保存一个对象 185 /// </summary> 186 /// <typeparam name="T"></typeparam> 187 /// <param name="key"></param> 188 /// <param name="obj"></param> 189 /// <param name="expiry"></param> 190 /// <returns></returns> 191 public async Task<bool> StringSetAsync<T>(string key, T obj, TimeSpan? expiry = default(TimeSpan?)) 192  { 193 key = AddSysCustomKey(key); 194 string json = ConvertJson(obj); 195 return await Do(db => db.StringSetAsync(key, json, expiry)); 196  } 197  198 /// <summary> 199 /// 获取单个key的值 200 /// </summary> 201 /// <param name="key">Redis Key</param> 202 /// <returns></returns> 203 public async Task<string> StringGetAsync(string key) 204  { 205 key = AddSysCustomKey(key); 206 return await Do(db => db.StringGetAsync(key)); 207  } 208  209 /// <summary> 210 /// 获取多个Key 211 /// </summary> 212 /// <param name="listKey">Redis Key集合</param> 213 /// <returns></returns> 214 public async Task<RedisValue[]> StringGetAsync(List<string> listKey) 215  { 216 List<string> newKeys = listKey.Select(AddSysCustomKey).ToList(); 217 return await Do(db => db.StringGetAsync(ConvertRedisKeys(newKeys))); 218  } 219  220 /// <summary> 221 /// 获取一个key的对象 222 /// </summary> 223 /// <typeparam name="T"></typeparam> 224 /// <param name="key"></param> 225 /// <returns></returns> 226 public async Task<T> StringGetAsync<T>(string key) 227  { 228 key = AddSysCustomKey(key); 229 string result = await Do(db => db.StringGetAsync(key)); 230 return ConvertObj<T>(result); 231  } 232  233 /// <summary> 234 /// 为数字增长val 235 /// </summary> 236 /// <param name="key"></param> 237 /// <param name="val">可以为负</param> 238 /// <returns>增长后的值</returns> 239 public async Task<double> StringIncrementAsync(string key, double val = 1) 240  { 241 key = AddSysCustomKey(key); 242 return await Do(db => db.StringIncrementAsync(key, val)); 243  } 244  245 /// <summary> 246 /// 为数字减少val 247 /// </summary> 248 /// <param name="key"></param> 249 /// <param name="val">可以为负</param> 250 /// <returns>减少后的值</returns> 251 public async Task<double> StringDecrementAsync(string key, double val = 1) 252  { 253 key = AddSysCustomKey(key); 254 return await Do(db => db.StringDecrementAsync(key, val)); 255  } 256  257 #endregion 异步方法 258  259 #endregion String 260  261 #region Hash 262  263 #region 同步方法 264  265 /// <summary> 266 /// 判断某个数据是否已经被缓存 267 /// </summary> 268 /// <param name="key"></param> 269 /// <param name="dataKey"></param> 270 /// <returns></returns> 271 public bool HashExists(string key, string dataKey) 272  { 273 key = AddSysCustomKey(key); 274 return Do(db => db.HashExists(key, dataKey)); 275  } 276  277 /// <summary> 278 /// 存储数据到hash表 279 /// </summary> 280 /// <typeparam name="T"></typeparam> 281 /// <param name="key"></param> 282 /// <param name="dataKey"></param> 283 /// <param name="t"></param> 284 /// <returns></returns> 285 public bool HashSet<T>(string key, string dataKey, T t) 286  { 287 key = AddSysCustomKey(key); 288 return Do(db => 289  { 290 string json = ConvertJson(t); 291 return db.HashSet(key, dataKey, json); 292  }); 293  } 294  295 /// <summary> 296 /// 移除hash中的某值 297 /// </summary> 298 /// <param name="key"></param> 299 /// <param name="dataKey"></param> 300 /// <returns></returns> 301 public bool HashDelete(string key, string dataKey) 302  { 303 key = AddSysCustomKey(key); 304 return Do(db => db.HashDelete(key, dataKey)); 305  } 306  307 /// <summary> 308 /// 移除hash中的多个值 309 /// </summary> 310 /// <param name="key"></param> 311 /// <param name="dataKeys"></param> 312 /// <returns></returns> 313 public long HashDelete(string key, List<RedisValue> dataKeys) 314  { 315 key = AddSysCustomKey(key); 316 return Do(db => db.HashDelete(key, dataKeys.ToArray())); 317  } 318  319 /// <summary> 320 /// 从hash表获取数据 321 /// </summary> 322 /// <typeparam name="T"></typeparam> 323 /// <param name="key"></param> 324 /// <param name="dataKey"></param> 325 /// <returns></returns> 326 public T HashGet<T>(string key, string dataKey) 327  { 328 key = AddSysCustomKey(key); 329 return Do(db => 330  { 331 string value = db.HashGet(key, dataKey); 332 return ConvertObj<T>(value); 333  }); 334  } 335  336 /// <summary> 337 /// 从hash表获取数据 338 /// </summary> 339 /// <typeparam name="T"></typeparam> 340 /// <param name="key"></param> 341 /// <param name="dataKey"></param> 342 /// <returns></returns> 343 public string HashGetString(string key, string dataKey) 344  { 345 key = AddSysCustomKey(key); 346 return Do(db => 347  { 348 return db.HashGet(key, dataKey); 349  }); 350  } 351  352 /// <summary> 353 /// 为数字增长val 354 /// </summary> 355 /// <param name="key"></param> 356 /// <param name="dataKey"></param> 357 /// <param name="val">可以为负</param> 358 /// <returns>增长后的值</returns> 359 public double HashIncrement(string key, string dataKey, double val = 1) 360  { 361 key = AddSysCustomKey(key); 362 return Do(db => db.HashIncrement(key, dataKey, val)); 363  } 364  365 /// <summary> 366 /// 为数字减少val 367 /// </summary> 368 /// <param name="key"></param> 369 /// <param name="dataKey"></param> 370 /// <param name="val">可以为负</param> 371 /// <returns>减少后的值</returns> 372 public double HashDecrement(string key, string dataKey, double val = 1) 373  { 374 key = AddSysCustomKey(key); 375 return Do(db => db.HashDecrement(key, dataKey, val)); 376  } 377  378 /// <summary> 379 /// 获取hashkey所有Redis key 380 /// </summary> 381 /// <typeparam name="T"></typeparam> 382 /// <param name="key"></param> 383 /// <returns></returns> 384 public List<T> HashKeys<T>(string key) 385  { 386 key = AddSysCustomKey(key); 387 return Do(db => 388  { 389 RedisValue[] values = db.HashKeys(key); 390 return ConvetList<T>(values); 391  }); 392  } 393  394 public List<string> HashKeysString<T>(string key) 395  { 396 key = AddSysCustomKey(key); 397 return Do<List<string>>(db => this.ConvertString<string>(db.HashKeys(key, CommandFlags.None))); 398  } 399  400 #endregion 同步方法 401  402 #region 异步方法 403  404 /// <summary> 405 /// 判断某个数据是否已经被缓存 406 /// </summary> 407 /// <param name="key"></param> 408 /// <param name="dataKey"></param> 409 /// <returns></returns> 410 public async Task<bool> HashExistsAsync(string key, string dataKey) 411  { 412 key = AddSysCustomKey(key); 413 return await Do(db => db.HashExistsAsync(key, dataKey)); 414  } 415  416 /// <summary> 417 /// 存储数据到hash表 418 /// </summary> 419 /// <typeparam name="T"></typeparam> 420 /// <param name="key"></param> 421 /// <param name="dataKey"></param> 422 /// <param name="t"></param> 423 /// <returns></returns> 424 public async Task<bool> HashSetAsync<T>(string key, string dataKey, T t) 425  { 426 key = AddSysCustomKey(key); 427 return await Do(db => 428  { 429 string json = ConvertJson(t); 430 return db.HashSetAsync(key, dataKey, json); 431  }); 432  } 433  434 /// <summary> 435 /// 移除hash中的某值 436 /// </summary> 437 /// <param name="key"></param> 438 /// <param name="dataKey"></param> 439 /// <returns></returns> 440 public async Task<bool> HashDeleteAsync(string key, string dataKey) 441  { 442 key = AddSysCustomKey(key); 443 return await Do(db => db.HashDeleteAsync(key, dataKey)); 444  } 445  446 /// <summary> 447 /// 移除hash中的多个值 448 /// </summary> 449 /// <param name="key"></param> 450 /// <param name="dataKeys"></param> 451 /// <returns></returns> 452 public async Task<long> HashDeleteAsync(string key, List<RedisValue> dataKeys) 453  { 454 key = AddSysCustomKey(key); 455 //List<RedisValue> dataKeys1 = new List<RedisValue>() {"1","2"}; 456 return await Do(db => db.HashDeleteAsync(key, dataKeys.ToArray())); 457  } 458  459 /// <summary> 460 /// 从hash表获取数据 461 /// </summary> 462 /// <typeparam name="T"></typeparam> 463 /// <param name="key"></param> 464 /// <param name="dataKey"></param> 465 /// <returns></returns> 466 public async Task<T> HashGeAsync<T>(string key, string dataKey) 467  { 468 key = AddSysCustomKey(key); 469 string value = await Do(db => db.HashGetAsync(key, dataKey)); 470 return ConvertObj<T>(value); 471  } 472  473 /// <summary> 474 /// 为数字增长val 475 /// </summary> 476 /// <param name="key"></param> 477 /// <param name="dataKey"></param> 478 /// <param name="val">可以为负</param> 479 /// <returns>增长后的值</returns> 480 public async Task<double> HashIncrementAsync(string key, string dataKey, double val = 1) 481  { 482 key = AddSysCustomKey(key); 483 return await Do(db => db.HashIncrementAsync(key, dataKey, val)); 484  } 485  486 /// <summary> 487 /// 为数字减少val 488 /// </summary> 489 /// <param name="key"></param> 490 /// <param name="dataKey"></param> 491 /// <param name="val">可以为负</param> 492 /// <returns>减少后的值</returns> 493 public async Task<double> HashDecrementAsync(string key, string dataKey, double val = 1) 494  { 495 key = AddSysCustomKey(key); 496 return await Do(db => db.HashDecrementAsync(key, dataKey, val)); 497  } 498  499 /// <summary> 500 /// 获取hashkey所有Redis key 501 /// </summary> 502 /// <typeparam name="T"></typeparam> 503 /// <param name="key"></param> 504 /// <returns></returns> 505 public async Task<List<T>> HashKeysAsync<T>(string key) 506  { 507 key = AddSysCustomKey(key); 508 RedisValue[] values = await Do(db => db.HashKeysAsync(key)); 509 return ConvetList<T>(values); 510  } 511  512 #endregion 异步方法 513  514 #endregion Hash 515  516 #region List 517  518 #region 同步方法 519  520 /// <summary> 521 /// 移除指定ListId的内部List的值 522 /// </summary> 523 /// <param name="key"></param> 524 /// <param name="value"></param> 525 public void ListRemove<T>(string key, T value) 526  { 527 key = AddSysCustomKey(key); 528 Do(db => db.ListRemove(key, ConvertJson(value))); 529  } 530  531 /// <summary> 532 /// 获取指定key的List 533 /// </summary> 534 /// <param name="key"></param> 535 /// <returns></returns> 536 public List<T> ListRange<T>(string key) 537  { 538 key = AddSysCustomKey(key); 539 return Do(redis => 540  { 541 var values = redis.ListRange(key); 542 return ConvetList<T>(values); 543  }); 544  } 545  546 /// <summary> 547 /// 入队 548 /// </summary> 549 /// <param name="key"></param> 550 /// <param name="value"></param> 551 public void ListRightPush<T>(string key, T value) 552  { 553 key = AddSysCustomKey(key); 554 Do(db => db.ListRightPush(key, ConvertJson(value))); 555  } 556  557 /// <summary> 558 /// 出队 559 /// </summary> 560 /// <typeparam name="T"></typeparam> 561 /// <param name="key"></param> 562 /// <returns></returns> 563 public T ListRightPop<T>(string key) 564  { 565 key = AddSysCustomKey(key); 566 return Do(db => 567  { 568 var value = db.ListRightPop(key); 569 return ConvertObj<T>(value); 570  }); 571  } 572  573 /// <summary> 574 /// 入栈 575 /// </summary> 576 /// <typeparam name="T"></typeparam> 577 /// <param name="key"></param> 578 /// <param name="value"></param> 579 public void ListLeftPush<T>(string key, T value) 580  { 581 key = AddSysCustomKey(key); 582 Do(db => db.ListLeftPush(key, ConvertJson(value))); 583  } 584  585 /// <summary> 586 /// 出栈 587 /// </summary> 588 /// <typeparam name="T"></typeparam> 589 /// <param name="key"></param> 590 /// <returns></returns> 591 public T ListLeftPop<T>(string key) 592  { 593 key = AddSysCustomKey(key); 594 return Do(db => 595  { 596 var value = db.ListLeftPop(key); 597 return ConvertObj<T>(value); 598  }); 599  } 600  601 /// <summary> 602 /// 出栈 603 /// </summary> 604 /// <typeparam name="T"></typeparam> 605 /// <param name="key"></param> 606 /// <returns></returns> 607 public string ListLeftPopString(string key) 608  { 609 key = AddSysCustomKey(key); 610 return Do(db => 611  { 612 return db.ListLeftPop(key); 613  }); 614  } 615  616 /// <summary> 617 /// 获取集合中的数量 618 /// </summary> 619 /// <param name="key"></param> 620 /// <returns></returns> 621 public long ListLength(string key) 622  { 623 key = AddSysCustomKey(key); 624 return Do(redis => redis.ListLength(key)); 625  } 626  627 #endregion 同步方法 628  629 #region 异步方法 630  631 /// <summary> 632 /// 移除指定ListId的内部List的值 633 /// </summary> 634 /// <param name="key"></param> 635 /// <param name="value"></param> 636 public async Task<long> ListRemoveAsync<T>(string key, T value) 637  { 638 key = AddSysCustomKey(key); 639 return await Do(db => db.ListRemoveAsync(key, ConvertJson(value))); 640  } 641  642 /// <summary> 643 /// 获取指定key的List 644 /// </summary> 645 /// <param name="key"></param> 646 /// <returns></returns> 647 public async Task<List<T>> ListRangeAsync<T>(string key) 648  { 649 key = AddSysCustomKey(key); 650 var values = await Do(redis => redis.ListRangeAsync(key)); 651 return ConvetList<T>(values); 652  } 653  654 /// <summary> 655 /// 入队 656 /// </summary> 657 /// <param name="key"></param> 658 /// <param name="value"></param> 659 public async Task<long> ListRightPushAsync<T>(string key, T value) 660  { 661 key = AddSysCustomKey(key); 662 return await Do(db => db.ListRightPushAsync(key, ConvertJson(value))); 663  } 664  665 /// <summary> 666 /// 出队 667 /// </summary> 668 /// <typeparam name="T"></typeparam> 669 /// <param name="key"></param> 670 /// <returns></returns> 671 public async Task<T> ListRightPopAsync<T>(string key) 672  { 673 key = AddSysCustomKey(key); 674 var value = await Do(db => db.ListRightPopAsync(key)); 675 return ConvertObj<T>(value); 676  } 677  678 /// <summary> 679 /// 入栈 680 /// </summary> 681 /// <typeparam name="T"></typeparam> 682 /// <param name="key"></param> 683 /// <param name="value"></param> 684 public async Task<long> ListLeftPushAsync<T>(string key, T value) 685  { 686 key = AddSysCustomKey(key); 687 return await Do(db => db.ListLeftPushAsync(key, ConvertJson(value))); 688  } 689  690 /// <summary> 691 /// 出栈 692 /// </summary> 693 /// <typeparam name="T"></typeparam> 694 /// <param name="key"></param> 695 /// <returns></returns> 696 public async Task<T> ListLeftPopAsync<T>(string key) 697  { 698 key = AddSysCustomKey(key); 699 var value = await Do(db => db.ListLeftPopAsync(key)); 700 return ConvertObj<T>(value); 701  } 702  703 /// <summary> 704 /// 获取集合中的数量 705 /// </summary> 706 /// <param name="key"></param> 707 /// <returns></returns> 708 public async Task<long> ListLengthAsync(string key) 709  { 710 key = AddSysCustomKey(key); 711 return await Do(redis => redis.ListLengthAsync(key)); 712  } 713  714 #endregion 异步方法 715  716 #endregion List 717  718 #region SortedSet 有序集合 719  720 #region 同步方法 721  722 /// <summary> 723 /// 添加 724 /// </summary> 725 /// <param name="key"></param> 726 /// <param name="value"></param> 727 /// <param name="score"></param> 728 public bool SortedSetAdd<T>(string key, T value, double score) 729  { 730 key = AddSysCustomKey(key); 731 return Do(redis => redis.SortedSetAdd(key, ConvertJson<T>(value), score)); 732  } 733  734 /// <summary> 735 /// 删除 736 /// </summary> 737 /// <param name="key"></param> 738 /// <param name="value"></param> 739 public bool SortedSetRemove<T>(string key, T value) 740  { 741 key = AddSysCustomKey(key); 742 return Do(redis => redis.SortedSetRemove(key, ConvertJson(value))); 743  } 744  745 /// <summary> 746 /// 获取全部 747 /// </summary> 748 /// <param name="key"></param> 749 /// <returns></returns> 750 public List<T> SortedSetRangeByRank<T>(string key) 751  { 752 key = AddSysCustomKey(key); 753 return Do(redis => 754  { 755 var values = redis.SortedSetRangeByRank(key); 756 return ConvetList<T>(values); 757  }); 758  } 759  760 /// <summary> 761 /// 获取集合中的数量 762 /// </summary> 763 /// <param name="key"></param> 764 /// <returns></returns> 765 public long SortedSetLength(string key) 766  { 767 key = AddSysCustomKey(key); 768 return Do(redis => redis.SortedSetLength(key)); 769  } 770  771 #endregion 同步方法 772  773 #region 异步方法 774  775 /// <summary> 776 /// 添加 777 /// </summary> 778 /// <param name="key"></param> 779 /// <param name="value"></param> 780 /// <param name="score"></param> 781 public async Task<bool> SortedSetAddAsync<T>(string key, T value, double score) 782  { 783 key = AddSysCustomKey(key); 784 return await Do(redis => redis.SortedSetAddAsync(key, ConvertJson<T>(value), score)); 785  } 786  787 /// <summary> 788 /// 删除 789 /// </summary> 790 /// <param name="key"></param> 791 /// <param name="value"></param> 792 public async Task<bool> SortedSetRemoveAsync<T>(string key, T value) 793  { 794 key = AddSysCustomKey(key); 795 return await Do(redis => redis.SortedSetRemoveAsync(key, ConvertJson(value))); 796  } 797  798 /// <summary> 799 /// 获取全部 800 /// </summary> 801 /// <param name="key"></param> 802 /// <returns></returns> 803 public async Task<List<T>> SortedSetRangeByRankAsync<T>(string key) 804  { 805 key = AddSysCustomKey(key); 806 var values = await Do(redis => redis.SortedSetRangeByRankAsync(key)); 807 return ConvetList<T>(values); 808  } 809  810 /// <summary> 811 /// 获取集合中的数量 812 /// </summary> 813 /// <param name="key"></param> 814 /// <returns></returns> 815 public async Task<long> SortedSetLengthAsync(string key) 816  { 817 key = AddSysCustomKey(key); 818 return await Do(redis => redis.SortedSetLengthAsync(key)); 819  } 820  821 #endregion 异步方法 822  823 #endregion SortedSet 有序集合 824  825 #region key 826  827 /// <summary> 828 /// 删除单个key 829 /// </summary> 830 /// <param name="key">redis key</param> 831 /// <returns>是否删除成功</returns> 832 public bool KeyDelete(string key) 833  { 834 key = AddSysCustomKey(key); 835 return Do(db => db.KeyDelete(key)); 836  } 837  838 /// <summary> 839 /// 删除多个key 840 /// </summary> 841 /// <param name="keys">rediskey</param> 842 /// <returns>成功删除的个数</returns> 843 public long KeyDelete(List<string> keys) 844  { 845 List<string> newKeys = keys.Select(AddSysCustomKey).ToList(); 846 return Do(db => db.KeyDelete(ConvertRedisKeys(newKeys))); 847  } 848  849 /// <summary> 850 /// 判断key是否存储 851 /// </summary> 852 /// <param name="key">redis key</param> 853 /// <returns></returns> 854 public bool KeyExists(string key) 855  { 856 key = AddSysCustomKey(key); 857 return Do(db => db.KeyExists(key)); 858  } 859  860 /// <summary> 861 /// 重新命名key 862 /// </summary> 863 /// <param name="key">就的redis key</param> 864 /// <param name="newKey">新的redis key</param> 865 /// <returns></returns> 866 public bool KeyRename(string key, string newKey) 867  { 868 key = AddSysCustomKey(key); 869 return Do(db => db.KeyRename(key, newKey)); 870  } 871  872 /// <summary> 873 /// 设置Key的时间 874 /// </summary> 875 /// <param name="key">redis key</param> 876 /// <param name="expiry"></param> 877 /// <returns></returns> 878 public bool KeyExpire(string key, TimeSpan? expiry = default(TimeSpan?)) 879  { 880 key = AddSysCustomKey(key); 881 return Do(db => db.KeyExpire(key, expiry)); 882  } 883  884 #endregion key 885  886 #region 发布订阅 887  888 /// <summary> 889 /// Redis发布订阅 订阅 890 /// </summary> 891 /// <param name="subChannel"></param> 892 /// <param name="handler"></param> 893 public void Subscribe(string subChannel, Action<RedisChannel, RedisValue> handler = null) 894  { 895 ISubscriber sub = _conn.GetSubscriber(); 896 sub.Subscribe(subChannel, (channel, message) => 897  { 898 if (handler == null) 899  { 900 Console.WriteLine(subChannel + " 订阅收到消息:" + message); 901  } 902 else 903  { 904  handler(channel, message); 905  } 906  }); 907  } 908  909 /// <summary> 910 /// Redis发布订阅 发布 911 /// </summary> 912 /// <typeparam name="T"></typeparam> 913 /// <param name="channel"></param> 914 /// <param name="msg"></param> 915 /// <returns></returns> 916 public long Publish<T>(string channel, T msg) 917  { 918 ISubscriber sub = _conn.GetSubscriber(); 919 return sub.Publish(channel, ConvertJson(msg)); 920  } 921  922 /// <summary> 923 /// Redis发布订阅 取消订阅 924 /// </summary> 925 /// <param name="channel"></param> 926 public void Unsubscribe(string channel) 927  { 928 ISubscriber sub = _conn.GetSubscriber(); 929  sub.Unsubscribe(channel); 930  } 931  932 /// <summary> 933 /// Redis发布订阅 取消全部订阅 934 /// </summary> 935 public void UnsubscribeAll() 936  { 937 ISubscriber sub = _conn.GetSubscriber(); 938  sub.UnsubscribeAll(); 939  } 940  941 #endregion 发布订阅 942  943 #region 其他 944  945 public ITransaction CreateTransaction() 946  { 947 return GetDatabase().CreateTransaction(); 948  } 949  950 public IDatabase GetDatabase() 951  { 952 return _conn.GetDatabase(DbNum); 953  } 954  955 public IServer GetServer(string hostAndPort) 956  { 957 return _conn.GetServer(hostAndPort); 958  } 959  960 /// <summary> 961 /// 设置前缀 962 /// </summary> 963 /// <param name="customKey"></param> 964 public void SetSysCustomKey(string customKey) 965  { 966 CustomKey = customKey; 967  } 968  969 /// <summary> 970 /// 删除集合 971 /// </summary> 972 /// <param name="redisKey"></param> 973 /// <param name="databaseNum"></param> 974 /// <returns></returns> 975 public bool KeyRemove(string redisKey) 976  { 977 var database = _conn.GetDatabase(DbNum); 978 return database.KeyDelete(redisKey); 979  } 980  981 #endregion 其他 982  983 #region 辅助方法 984  985 private string AddSysCustomKey(string oldKey) 986  { 987 var prefixKey = CustomKey ?? RedisConnectionHelp.SysCustomKey; 988 return prefixKey + oldKey; 989  } 990  991 private T Do<T>(Func<IDatabase, T> func) 992  { 993 var database = _conn.GetDatabase(DbNum); 994 return func(database); 995  } 996  997 private string ConvertJson<T>(T value) 998  { 999 string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value);1000 return result;1001  }1002 1003 private T ConvertObj<T>(RedisValue value)1004  {1005 if (value.IsNull)1006 return default(T);1007 return JsonConvert.DeserializeObject<T>(value);1008  }1009 1010 private List<T> ConvetList<T>(RedisValue[] values)1011  {1012 if (values == null)1013 return null;1014 1015 List<T> result = new List<T>();1016 foreach (var item in values)1017  {1018 var model = ConvertObj<T>(item);1019  result.Add(model);1020  }1021 return result;1022  }1023 1024 private List<string> ConvertString<T>(RedisValue[] values)1025  {1026 List<string> list = new List<string>();1027 if (values == null)1028  {1029 return null;1030  }1031 foreach (RedisValue value2 in values)1032  {1033  list.Add(value2.ToString());1034  }1035 return list;1036  }1037 1038 private RedisKey[] ConvertRedisKeys(List<string> redisKeys)1039  {1040 return redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray();1041  }1042 1043 #endregion 辅助方法1044 }

View Code

 

  测试中用到的HashSet和Get方法,其他的使用到的可以测试下,

1 public bool HashSet<T>(string key, string dataKey, T t)2  {3 key = AddSysCustomKey(key);4 return Do(db =>5  {6 string json = ConvertJson(t);7 return db.HashSet(key, dataKey, json);8  });9 }

  ④ Main函数中的测试用例,也只是简单测试了下,

 1 string key = "123456"; 2 string dataKey = "123456"; 3  4 redisHelper.HashSet(key, dataKey, "123456"); 5  6 string x = redisHelper.HashGetString(key, dataKey); 7 Console.WriteLine("x = {0}", x); 8  9 10 Student student = new Student { Age = 11, Name = "Jack" };11 redisHelper = new RedisHelper(1);12  redisHelper.HashSet(key, dataKey, student);13 14 Student getStu = redisHelper.HashGet<Student>(key, dataKey);15 if(getStu != null)16  {17 Console.WriteLine("Name = {0}, Age = {1}.", getStu.Name, getStu.Age);18  }19 else20  {21 Console.WriteLine("Get student failure.");22 }

 

  输出结果:

技术图片

  查看Redis缓存中存储的数据,使用Redis客户端进行查看,因为代码中间redisHelper进行了重新构造,所以下图会在两个DB中。

技术图片

 

 

 技术图片

 

 

  Redis中值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。

 测试下,队列在Redis中的应用,入队(左进右出,右进左出都有,组合就是栈和队列啦),redisHelper.ListRightPush("PushTest", student);

 再用Redis客户端查看,与用Hash保存的不一样,Redis队列也可以放心使用,日活百万以下没什么问题,再往上考虑Kafka呀,

技术图片

 

 

   使用ListLeftPop,右进左出的队列,代码:

 1 Console.WriteLine("0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0"); 2  3 for(int i = 0; i < 3; i++) 4  { 5 student = new Student { Age = 11 + i, Name = string.Format("Jack {0}", i) }; 6 redisHelper.ListRightPush("PushTest", student); 7  } 8  9 getStu = redisHelper.ListLeftPop<Student>("PushTest");10 while (getStu != null)11  {12 Console.WriteLine("Name = {0}, Age = {1}.", getStu.Name, getStu.Age);13 getStu = redisHelper.ListLeftPop<Student>("PushTest");14 }

  运行输出,前两个是刚才执行入队一个,现在执行一次程序又入队一个,所以,取出五个,与放入顺序一致,先进先出。

技术图片

 

相关文章