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             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<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             }

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

 

posted @ 2020-06-14 13:37  7嗨嗨  阅读(2034)  评论(3编辑  收藏  举报