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和端口,
② ConnectionMultiplexer封装
ConnectionMultiplexer对象是StackExchange.Redis最中枢的对象。这个类的实例需要被整个应用程序域共享和重用的,所以不需要在每个操作中不停的创建该对象的实例,一般都是使用单例来创建和存放这个对象,提高程序运行的效率,这个在官网上也有说明的。
1 ///2 /// ConnectionMultiplexer对象管理帮助类 3 /// 4 public static class RedisConnectionHelp 5 { 6 #region 属性 7 8 /// 9 /// 系统自定义Key前缀 10 /// 11 public static readonly string SysCustomKey = ConfigurationManager.AppSettings["redisKey"] ?? ""; 12 13 /// 14 /// Redis链接字符串 15 /// 16 private static readonly string RedisConnectionString = ConfigurationManager.ConnectionStrings["RedisExchangeHosts"].ConnectionString; 17 18 /// 19 /// 链接缓存池 20 /// 21 private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string, ConnectionMultiplexer>(); 22 23 #endregion 24 25 #region 单例和构造 26 27 /// 28 /// 锁 29 /// 30 private static readonly object Locker = new object(); 31 32 /// 33 /// 单例 34 /// 35 private static ConnectionMultiplexer _instance; 36 37 38 /// 39 /// 单例获取 40 /// 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 /// 60 /// 缓存获取 61 /// 62 /// 63 /// 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 /// 74 /// 获取链接 75 /// 76 /// 77 /// 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 /// 99 /// 配置更改时 100 /// 101 /// 102 /// 103 private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e) 104 { 105 Console.WriteLine("Configuration changed: " + e.EndPoint); 106 } 107 108 /// 109 /// 发生错误时 110 /// 111 /// 112 /// 113 private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e) 114 { 115 Console.WriteLine("ErrorMessage: " + e.Message); 116 } 117 118 /// 119 /// 重新建立连接之前的错误 120 /// 121 /// 122 /// 123 private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e) 124 { 125 Console.WriteLine("ConnectionRestored: " + e.EndPoint); 126 } 127 128 /// 129 /// 连接失败 , 如果重新连接成功你将不会收到这个通知 130 /// 131 /// 132 /// 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 /// 139 /// 更改集群 140 /// 141 /// 142 /// 143 private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e) 144 { 145 Console.WriteLine("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint); 146 } 147 148 /// 149 /// redis类库错误 150 /// 151 /// 152 /// 153 private static void MuxerInternalError(object sender, InternalErrorEventArgs e) 154 { 155 Console.WriteLine("InternalError:Message" + e.Exception.Message); 156 } 157 158 #endregion 事件 159 }
③ RedisHelper通用操作类封装
1 ///2 /// Redis操作类 3 /// 4 public class RedisHelper 5 { 6 #region 属性 7 8 /// 9 /// DB库 10 /// 11 private int DbNum { get; } 12 13 /// 14 /// Redis链接 15 /// 16 private readonly ConnectionMultiplexer _conn; 17 18 /// 19 /// 前缀 20 /// 21 public string CustomKey; 22 23 #endregion 24 25 #region 构造函数 26 27 /// 28 /// 默认构造 29 /// 30 /// DB索引 31 public RedisHelper(int dbNum = 0) 32 : this(dbNum, null) 33 { 34 } 35 36 /// 37 /// 构造 38 /// 39 /// 40 /// 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 /// 57 /// 保存单个key value 58 /// 59 /// Redis Key 60 /// 保存的值 61 /// 过期时间 62 /// 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 /// 70 /// 保存多个key value 71 /// 72 /// 键值对 73 /// 74 public bool StringSet(List > keyValues) 75 { 76 List > newkeyValues = 77 keyValues.Select(p => new KeyValuePair (AddSysCustomKey(p.Key), p.Value)).ToList(); 78 return Do(db => db.StringSet(newkeyValues.ToArray())); 79 } 80 81 /// 82 /// 保存一个对象 83 /// 84 /// 85 /// 86 /// 87 /// 88 /// 89 public bool StringSet (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 /// 97 /// 获取单个key的值 98 /// 99 /// Redis Key 100 /// 101 public string StringGet(string key) 102 { 103 key = AddSysCustomKey(key); 104 return Do(db => db.StringGet(key)); 105 } 106 107 /// 108 /// 获取多个Key 109 /// 110 /// Redis Key集合 111 /// 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 /// 119 /// 获取一个key的对象 120 /// 121 /// 122 /// 123 /// 124 public T StringGet (string key) 125 { 126 key = AddSysCustomKey(key); 127 return Do(db => ConvertObj (db.StringGet(key))); 128 } 129 130 /// 131 /// 为数字增长val 132 /// 133 /// 134 /// 可以为负 135 /// 增长后的值 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 /// 143 /// 为数字减少val 144 /// 145 /// 146 /// 可以为负 147 /// 减少后的值 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 /// 159 /// 保存单个key value 160 /// 161 /// Redis Key 162 /// 保存的值 163 /// 过期时间 164 /// 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 /// 172 /// 保存多个key value 173 /// 174 /// 键值对 175 /// 176 public async Task<bool> StringSetAsync(List > keyValues) 177 { 178 List > newkeyValues = 179 keyValues.Select(p => new KeyValuePair (AddSysCustomKey(p.Key), p.Value)).ToList(); 180 return await Do(db => db.StringSetAsync(newkeyValues.ToArray())); 181 } 182 183 /// 184 /// 保存一个对象 185 /// 186 /// 187 /// 188 /// 189 /// 190 /// 191 public async Task<bool> StringSetAsync (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 /// 199 /// 获取单个key的值 200 /// 201 /// Redis Key 202 /// 203 public async Task<string> StringGetAsync(string key) 204 { 205 key = AddSysCustomKey(key); 206 return await Do(db => db.StringGetAsync(key)); 207 } 208 209 /// 210 /// 获取多个Key 211 /// 212 /// Redis Key集合 213 /// 214 public async Task 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 /// 221 /// 获取一个key的对象 222 /// 223 /// 224 /// 225 /// 226 public async Task StringGetAsync (string key) 227 { 228 key = AddSysCustomKey(key); 229 string result = await Do(db => db.StringGetAsync(key)); 230 return ConvertObj (result); 231 } 232 233 /// 234 /// 为数字增长val 235 /// 236 /// 237 /// 可以为负 238 /// 增长后的值 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 /// 246 /// 为数字减少val 247 /// 248 /// 249 /// 可以为负 250 /// 减少后的值 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 /// 266 /// 判断某个数据是否已经被缓存 267 /// 268 /// 269 /// 270 /// 271 public bool HashExists(string key, string dataKey) 272 { 273 key = AddSysCustomKey(key); 274 return Do(db => db.HashExists(key, dataKey)); 275 } 276 277 /// 278 /// 存储数据到hash表 279 /// 280 /// 281 /// 282 /// 283 /// 284 /// 285 public bool HashSet (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 /// 296 /// 移除hash中的某值 297 /// 298 /// 299 /// 300 /// 301 public bool HashDelete(string key, string dataKey) 302 { 303 key = AddSysCustomKey(key); 304 return Do(db => db.HashDelete(key, dataKey)); 305 } 306 307 /// 308 /// 移除hash中的多个值 309 /// 310 /// 311 /// 312 /// 313 public long HashDelete(string key, List dataKeys) 314 { 315 key = AddSysCustomKey(key); 316 return Do(db => db.HashDelete(key, dataKeys.ToArray())); 317 } 318 319 /// 320 /// 从hash表获取数据 321 /// 322 /// 323 /// 324 /// 325 /// 326 public T HashGet (string key, string dataKey) 327 { 328 key = AddSysCustomKey(key); 329 return Do(db => 330 { 331 string value = db.HashGet(key, dataKey); 332 return ConvertObj (value); 333 }); 334 } 335 336 /// 337 /// 从hash表获取数据 338 /// 339 /// 340 /// 341 /// 342 /// 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 /// 353 /// 为数字增长val 354 /// 355 /// 356 /// 357 /// 可以为负 358 /// 增长后的值 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 /// 366 /// 为数字减少val 367 /// 368 /// 369 /// 370 /// 可以为负 371 /// 减少后的值 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 /// 379 /// 获取hashkey所有Redis key 380 /// 381 /// 382 /// 383 /// 384 public List HashKeys (string key) 385 { 386 key = AddSysCustomKey(key); 387 return Do(db => 388 { 389 RedisValue[] values = db.HashKeys(key); 390 return ConvetList (values); 391 }); 392 } 393 394 public List<string> HashKeysString (string key) 395 { 396 key = AddSysCustomKey(key); 397 return Do string>>(db => this.ConvertString<string>(db.HashKeys(key, CommandFlags.None))); 398 } 399 400 #endregion 同步方法 401 402 #region 异步方法 403 404 ///
405 /// 判断某个数据是否已经被缓存 406 /// 407 /// 408 /// 409 /// 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 /// 417 /// 存储数据到hash表 418 /// 419 /// 420 /// 421 /// 422 /// 423 /// 424 public async Task<bool> HashSetAsync (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 /// 435 /// 移除hash中的某值 436 /// 437 /// 438 /// 439 /// 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 /// 447 /// 移除hash中的多个值 448 /// 449 /// 450 /// 451 /// 452 public async Task<long> HashDeleteAsync(string key, List dataKeys) 453 { 454 key = AddSysCustomKey(key); 455 //List dataKeys1 = new List 456 return await Do(db => db.HashDeleteAsync(key, dataKeys.ToArray())); 457 } 458 459 ///() {"1","2"}; 460 /// 从hash表获取数据 461 /// 462 /// 463 /// 464 /// 465 /// 466 public async Task HashGeAsync (string key, string dataKey) 467 { 468 key = AddSysCustomKey(key); 469 string value = await Do(db => db.HashGetAsync(key, dataKey)); 470 return ConvertObj (value); 471 } 472 473 /// 474 /// 为数字增长val 475 /// 476 /// 477 /// 478 /// 可以为负 479 /// 增长后的值 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 /// 487 /// 为数字减少val 488 /// 489 /// 490 /// 491 /// 可以为负 492 /// 减少后的值 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 /// 500 /// 获取hashkey所有Redis key 501 /// 502 /// 503 /// 504 /// 505 public async Task > HashKeysAsync
(string key) 506 { 507 key = AddSysCustomKey(key); 508 RedisValue[] values = await Do(db => db.HashKeysAsync(key)); 509 return ConvetList (values); 510 } 511 512 #endregion 异步方法 513 514 #endregion Hash 515 516 #region List 517 518 #region 同步方法 519 520 /// 521 /// 移除指定ListId的内部List的值 522 /// 523 /// 524 /// 525 public void ListRemove (string key, T value) 526 { 527 key = AddSysCustomKey(key); 528 Do(db => db.ListRemove(key, ConvertJson(value))); 529 } 530 531 /// 532 /// 获取指定key的List 533 /// 534 /// 535 /// 536 public List ListRange (string key) 537 { 538 key = AddSysCustomKey(key); 539 return Do(redis => 540 { 541 var values = redis.ListRange(key); 542 return ConvetList (values); 543 }); 544 } 545 546 /// 547 /// 入队 548 /// 549 /// 550 /// 551 public void ListRightPush (string key, T value) 552 { 553 key = AddSysCustomKey(key); 554 Do(db => db.ListRightPush(key, ConvertJson(value))); 555 } 556 557 /// 558 /// 出队 559 /// 560 /// 561 /// 562 /// 563 public T ListRightPop (string key) 564 { 565 key = AddSysCustomKey(key); 566 return Do(db => 567 { 568 var value = db.ListRightPop(key); 569 return ConvertObj (value); 570 }); 571 } 572 573 /// 574 /// 入栈 575 /// 576 /// 577 /// 578 /// 579 public void ListLeftPush (string key, T value) 580 { 581 key = AddSysCustomKey(key); 582 Do(db => db.ListLeftPush(key, ConvertJson(value))); 583 } 584 585 /// 586 /// 出栈 587 /// 588 /// 589 /// 590 /// 591 public T ListLeftPop (string key) 592 { 593 key = AddSysCustomKey(key); 594 return Do(db => 595 { 596 var value = db.ListLeftPop(key); 597 return ConvertObj (value); 598 }); 599 } 600 601 /// 602 /// 出栈 603 /// 604 /// 605 /// 606 /// 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 /// 617 /// 获取集合中的数量 618 /// 619 /// 620 /// 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 /// 632 /// 移除指定ListId的内部List的值 633 /// 634 /// 635 /// 636 public async Task<long> ListRemoveAsync (string key, T value) 637 { 638 key = AddSysCustomKey(key); 639 return await Do(db => db.ListRemoveAsync(key, ConvertJson(value))); 640 } 641 642 /// 643 /// 获取指定key的List 644 /// 645 /// 646 /// 647 public async Task > ListRangeAsync
(string key) 648 { 649 key = AddSysCustomKey(key); 650 var values = await Do(redis => redis.ListRangeAsync(key)); 651 return ConvetList (values); 652 } 653 654 /// 655 /// 入队 656 /// 657 /// 658 /// 659 public async Task<long> ListRightPushAsync (string key, T value) 660 { 661 key = AddSysCustomKey(key); 662 return await Do(db => db.ListRightPushAsync(key, ConvertJson(value))); 663 } 664 665 /// 666 /// 出队 667 /// 668 /// 669 /// 670 /// 671 public async Task ListRightPopAsync (string key) 672 { 673 key = AddSysCustomKey(key); 674 var value = await Do(db => db.ListRightPopAsync(key)); 675 return ConvertObj (value); 676 } 677 678 /// 679 /// 入栈 680 /// 681 /// 682 /// 683 /// 684 public async Task<long> ListLeftPushAsync (string key, T value) 685 { 686 key = AddSysCustomKey(key); 687 return await Do(db => db.ListLeftPushAsync(key, ConvertJson(value))); 688 } 689 690 /// 691 /// 出栈 692 /// 693 /// 694 /// 695 /// 696 public async Task ListLeftPopAsync (string key) 697 { 698 key = AddSysCustomKey(key); 699 var value = await Do(db => db.ListLeftPopAsync(key)); 700 return ConvertObj (value); 701 } 702 703 /// 704 /// 获取集合中的数量 705 /// 706 /// 707 /// 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 /// 723 /// 添加 724 /// 725 /// 726 /// 727 /// 728 public bool SortedSetAdd (string key, T value, double score) 729 { 730 key = AddSysCustomKey(key); 731 return Do(redis => redis.SortedSetAdd(key, ConvertJson (value), score)); 732 } 733 734 /// 735 /// 删除 736 /// 737 /// 738 /// 739 public bool SortedSetRemove (string key, T value) 740 { 741 key = AddSysCustomKey(key); 742 return Do(redis => redis.SortedSetRemove(key, ConvertJson(value))); 743 } 744 745 /// 746 /// 获取全部 747 /// 748 /// 749 /// 750 public List SortedSetRangeByRank (string key) 751 { 752 key = AddSysCustomKey(key); 753 return Do(redis => 754 { 755 var values = redis.SortedSetRangeByRank(key); 756 return ConvetList (values); 757 }); 758 } 759 760 /// 761 /// 获取集合中的数量 762 /// 763 /// 764 /// 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 /// 776 /// 添加 777 /// 778 /// 779 /// 780 /// 781 public async Task<bool> SortedSetAddAsync (string key, T value, double score) 782 { 783 key = AddSysCustomKey(key); 784 return await Do(redis => redis.SortedSetAddAsync(key, ConvertJson (value), score)); 785 } 786 787 /// 788 /// 删除 789 /// 790 /// 791 /// 792 public async Task<bool> SortedSetRemoveAsync (string key, T value) 793 { 794 key = AddSysCustomKey(key); 795 return await Do(redis => redis.SortedSetRemoveAsync(key, ConvertJson(value))); 796 } 797 798 /// 799 /// 获取全部 800 /// 801 /// 802 /// 803 public async Task > SortedSetRangeByRankAsync
(string key) 804 { 805 key = AddSysCustomKey(key); 806 var values = await Do(redis => redis.SortedSetRangeByRankAsync(key)); 807 return ConvetList (values); 808 } 809 810 /// 811 /// 获取集合中的数量 812 /// 813 /// 814 /// 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 /// 828 /// 删除单个key 829 /// 830 /// redis key 831 /// 是否删除成功 832 public bool KeyDelete(string key) 833 { 834 key = AddSysCustomKey(key); 835 return Do(db => db.KeyDelete(key)); 836 } 837 838 /// 839 /// 删除多个key 840 /// 841 /// rediskey 842 /// 成功删除的个数 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 /// 850 /// 判断key是否存储 851 /// 852 /// redis key 853 /// 854 public bool KeyExists(string key) 855 { 856 key = AddSysCustomKey(key); 857 return Do(db => db.KeyExists(key)); 858 } 859 860 /// 861 /// 重新命名key 862 /// 863 /// 就的redis key 864 /// 新的redis key 865 /// 866 public bool KeyRename(string key, string newKey) 867 { 868 key = AddSysCustomKey(key); 869 return Do(db => db.KeyRename(key, newKey)); 870 } 871 872 /// 873 /// 设置Key的时间 874 /// 875 /// redis key 876 /// 877 /// 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 /// 889 /// Redis发布订阅 订阅 890 /// 891 /// 892 /// 893 public void Subscribe(string subChannel, Action 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 /// 910 /// Redis发布订阅 发布 911 /// 912 /// 913 /// 914 /// 915 /// 916 public long Publish (string channel, T msg) 917 { 918 ISubscriber sub = _conn.GetSubscriber(); 919 return sub.Publish(channel, ConvertJson(msg)); 920 } 921 922 /// 923 /// Redis发布订阅 取消订阅 924 /// 925 /// 926 public void Unsubscribe(string channel) 927 { 928 ISubscriber sub = _conn.GetSubscriber(); 929 sub.Unsubscribe(channel); 930 } 931 932 /// 933 /// Redis发布订阅 取消全部订阅 934 /// 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 /// 961 /// 设置前缀 962 /// 963 /// 964 public void SetSysCustomKey(string customKey) 965 { 966 CustomKey = customKey; 967 } 968 969 /// 970 /// 删除集合 971 /// 972 /// 973 /// 974 /// 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 (Func func) 992 { 993 var database = _conn.GetDatabase(DbNum); 994 return func(database); 995 } 996 997 private string ConvertJson (T value) 998 { 999 string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value); 1000 return result; 1001 } 1002 1003 private T ConvertObj (RedisValue value) 1004 { 1005 if (value.IsNull) 1006 return default(T); 1007 return JsonConvert.DeserializeObject (value); 1008 } 1009 1010 private List ConvetList (RedisValue[] values) 1011 { 1012 if (values == null) 1013 return null; 1014 1015 List result = new List (); 1016 foreach (var item in values) 1017 { 1018 var model = ConvertObj (item); 1019 result.Add(model); 1020 } 1021 return result; 1022 } 1023 1024 private List<string> ConvertString (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 }
测试中用到的HashSet和Get方法,其他的使用到的可以测试下,
1 public bool HashSet(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(key, dataKey); 15 if(getStu != null) 16 { 17 Console.WriteLine("Name = {0}, Age = {1}.", getStu.Name, getStu.Age); 18 } 19 else 20 { 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("PushTest"); 10 while (getStu != null) 11 { 12 Console.WriteLine("Name = {0}, Age = {1}.", getStu.Name, getStu.Age); 13 getStu = redisHelper.ListLeftPop ("PushTest"); 14 }
运行输出,前两个是刚才执行入队一个,现在执行一次程序又入队一个,所以,取出五个,与放入顺序一致,先进先出。