设为首页 收藏本站
查看: 1563|回复: 0

[经验分享] C#中使用Redis学习二 在.NET4.5中使用redis hash操作

[复制链接]
累计签到:29 天
连续签到:1 天
发表于 2015-7-19 12:18:10 | 显示全部楼层 |阅读模式
  上一篇>>
  摘要

  上一篇讲述了安装redis客户端和服务器端,也大体地介绍了一下redis。本篇着重讲解.NET4.0 和 .NET4.5中如何使用redis和C# redis操作哈希表。并且会将封装的一些代码贴一下。在讲解的过程中,我打算结合redis操作命令一起叙述,算是作为对比吧。这样也能让读者清楚了 解,所分装的代码对应的redis的哪一些操作命令。

  hash哈希表简介

    这里仅仅是对哈希表作简单概念级介绍(摘自csdn),如果需要,自己去研究。
  1、哈希表的概念
    哈希表(Hash Table)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构。它通过把关键码值映射到哈希表中的一个位置来访问记录,以加快查找的速度。这个映射函数就做散列函数,存放记录的数组叫做散列表。
  2、哈希表查找的时间复杂度
    哈希表存储的是键值对,其查找的时间复杂度与元素数量多少无关,哈希表在查找元素时是通过计算哈希码值来定位元素的位置从而直接访问元素的,因此,哈希表查找的时间复杂度为O(1)。
  如何在.NET4.0/4.5中安装redis组件?

    在上一篇博文中,安装好的redis服务器端,要记得开启服务。然后再在.NET4.5(.NET4.0同理)项目中添加对redis操作的dll文件的引用。引用的步骤如下:
  第一步:右键项目中的引用,选择“管理NuGet程序包”;
  第二步:在搜索栏中输入“Redis client for the Redis NoSQL DB”,联机查找;如下图:
DSC0000.jpg
    联机搜索结构中的第一个(如上图红色区域的组件,其版本号为4.0.35)就是要安装的组件了。接下来我们就继续点击“安装”按钮,进入下载组件,等下载完成后,继续选择“接受条款”,然后继续安装。安装过程中会出现下图情况:
DSC0001.jpg
   
 这句红色错误的意思是我们安装的ServiceStack.Interfaces
4.0.35版本与当前的.NET4.5框架中组件不兼容。这说明我们需要降低或是提高.NET版本解决此问题。我安装的是.NET4.5,所以我只能降
低版本。降低.NET版本的方法大家应该都知道的。我就在累述一次,希望大家不要嫌烦,毕竟还有新手在。方法:右键项目文件选择“属性”==》“应用程
序”==》“目标框架”,然后选择各个版本去尝试之前的两步操作,直到可以安装为止。
   
 我试过了,.NET4.0也会遇到同样问题,直到.NET3.5才可以。当然此时安装的ServiceStack.Interfaces
版本是1.0.0.0
,这样我们再把.NET版本恢复4.5即可使用了。,其实是变相在.NET4.0/4.5下使用redis客户端。不知道各位有没有遇到这样的问题,还是
直接拷贝别人的dll文件。当自己亲自去操作的时候,才会发现,其实就算是安装一个组件都可能会出现各种各样的问题。所以,要想了解全过程的话,我们还是
要身体力行的啊。好了,这样就说明在.NET4.5下安装好了redis client了。
  实战:在项目中运用redis代码详解

    这部分主要是讲解怎样连接到redis服务器。其中包含很多配置,我就用代码去说明一切了。配置文件如下代码:



1  
2     
3  
4  

    在这里对RedisConfig这段配置文件的属性作下说明。
    WriteServerList:可写的Redis链接地址。
    ReadServerList:可读的Redis链接地址。
    MaxWritePoolSize:最大写链接数。
    MaxReadPoolSize:最大读链接数。
    AutoStart:自动重启。
    LocalCacheTime:本地缓存到期时间,单位:秒。
    RecordeLog:是否记录日志,该设置仅用于排查redis运行时出现的问题,如redis工作正常,请关闭该项。
    RedisConfigInfo类是记录redis连接信息,此信息和配置文件中的RedisConfig相呼应。cs代码如下:(这段代码不是我自己写的,但是我觉得应该这样设计。所以,copy了一下别人的代码。)


DSC0002.gif DSC0003.gif


  1 using System.Configuration;
  2
  3 namespace RedisDemo.Common.Redis
  4 {
  5     public sealed class RedisConfigInfo : ConfigurationSection
  6     {
  7         public static RedisConfigInfo GetConfig()
  8         {
  9             var section = (RedisConfigInfo)ConfigurationManager.GetSection("RedisConfig");
10             return section;
11         }
12         public static RedisConfigInfo GetConfig(string sectionName)
13         {
14             var section = (RedisConfigInfo)ConfigurationManager.GetSection("RedisConfig");
15             if (section == null)
16             {
17                 throw new ConfigurationErrorsException("Section " + sectionName + " is not found.");
18             }
19             return section;
20         }
21         ///
22         /// 可写的Redis链接地址
23         ///
24         [ConfigurationProperty("WriteServerList", IsRequired = false)]
25         public string WriteServerList
26         {
27             get
28             {
29                 return (string)base["WriteServerList"];
30             }
31             set
32             {
33                 base["WriteServerList"] = value;
34             }
35         }        
36         ///
37         /// 可读的Redis链接地址
38         ///
39         [ConfigurationProperty("ReadServerList", IsRequired = false)]
40         public string ReadServerList
41         {
42             get
43             {
44                 return (string)base["ReadServerList"];
45             }
46             set
47             {
48                 base["ReadServerList"] = value;
49             }
50         }        
51         ///
52         /// 最大写链接数
53         ///
54         [ConfigurationProperty("MaxWritePoolSize", IsRequired = false, DefaultValue = 5)]
55         public int MaxWritePoolSize
56         {
57             get
58             {
59                 var maxWritePoolSize = (int)base["MaxWritePoolSize"];
60                 return maxWritePoolSize > 0 ? maxWritePoolSize : 5;
61             }
62             set
63             {
64                 base["MaxWritePoolSize"] = value;
65             }
66         }        
67         ///
68         /// 最大读链接数
69         ///
70         [ConfigurationProperty("MaxReadPoolSize", IsRequired = false, DefaultValue = 5)]
71         public int MaxReadPoolSize
72         {
73             get
74             {
75                 var maxReadPoolSize = (int)base["MaxReadPoolSize"];
76                 return maxReadPoolSize > 0 ? maxReadPoolSize : 5;
77             }
78             set
79             {
80                 base["MaxReadPoolSize"] = value;
81             }
82         }        
83         ///
84         /// 自动重启
85         ///
86         [ConfigurationProperty("AutoStart", IsRequired = false, DefaultValue = true)]
87         public bool AutoStart
88         {
89             get
90             {
91                 return (bool)base["AutoStart"];
92             }
93             set
94             {
95                 base["AutoStart"] = value;
96             }
97         }        
98         ///
99         /// 本地缓存到期时间,单位:秒
100         ///
101         [ConfigurationProperty("LocalCacheTime", IsRequired = false, DefaultValue = 36000)]
102         public int LocalCacheTime
103         {
104             get
105             {
106                 return (int)base["LocalCacheTime"];
107             }
108             set
109             {
110                 base["LocalCacheTime"] = value;
111             }
112         }
113         ///
114         /// 是否记录日志,该设置仅用于排查redis运行时出现的问题,如redis工作正常,请关闭该项
115         ///
116         [ConfigurationProperty("RecordeLog", IsRequired = false, DefaultValue = false)]
117         public bool RecordeLog
118         {
119             get
120             {
121                 return (bool)base["RecordeLog"];
122             }
123             set
124             {
125                 base["RecordeLog"] = value;
126             }
127         }
128     }
129 }
RedisConfigInfo 类    RedisManager类主要是创建链接池管理对象的。





1 using System.Linq;
2 using ServiceStack.Redis;
3 using System.Collections.Generic;
4
5 namespace RedisDemo.Common.Redis
6 {
7     public class RedisManager
8     {
9         ///
10         /// redis配置文件信息
11         ///
12         private static readonly RedisConfigInfo RedisConfigInfo = RedisConfigInfo.GetConfig();
13
14         private static PooledRedisClientManager _prcm;
15
16         ///
17         /// 静态构造方法,初始化链接池管理对象
18         ///
19         static RedisManager()
20         {
21             CreateManager();
22         }
23         
24         ///
25         /// 创建链接池管理对象
26         ///
27         private static void CreateManager()
28         {
29             var writeServerList = SplitString(RedisConfigInfo.WriteServerList, ",");
30             var readServerList = SplitString(RedisConfigInfo.ReadServerList, ",");
31
32             _prcm = new PooledRedisClientManager(writeServerList,readServerList,
33                              new RedisClientManagerConfig
34                              {
35                                  MaxWritePoolSize = RedisConfigInfo.MaxWritePoolSize,
36                                  MaxReadPoolSize = RedisConfigInfo.MaxReadPoolSize,
37                                  AutoStart = RedisConfigInfo.AutoStart,
38                              });
39         }
40
41         private static IEnumerable SplitString(string strSource, string split)
42         {
43             return strSource.Split(split.ToArray());
44         }
45
46         ///
47         /// 客户端缓存操作对象
48         ///
49         public static IRedisClient GetClient()
50         {
51             if (_prcm == null)
52             {
53                 CreateManager();
54             }
55             return _prcm.GetClient();
56         }
57
58     }
59 }
RedisManager类  实战:封装redis对哈希表操作的代码

     实战中,我们操作redis最好还是要封装提炼一下的。提炼的目的是为了以后代码的重用。代码封装重用的好处我就不多说了,这个不是本次主要讨论的。下面是我所用项目中分装的代码,其中有的部分我修改过了,贴出来让大家看下。个人感觉不错:^_^
   RedisOperatorBase类,是redis操作的基类,继承自IDisposable接口,主要用于释放内存。





1 using System;
2 using ServiceStack.Redis;
3
4 namespace RedisDemo.Common.Redis.RedisOperator
5 {
6     public abstract class RedisOperatorBase : IDisposable
7     {
8         protected IRedisClient Redis { get; private set; }
9         private bool _disposed = false;
10         protected RedisOperatorBase()
11         {
12             Redis = RedisManager.GetClient();
13         }        
14         protected virtual void Dispose(bool disposing)
15         {
16             if (!this._disposed)
17             {
18                 if (disposing)
19                 {
20                     Redis.Dispose();
21                     Redis = null;
22                 }
23             }
24             this._disposed = true;
25         }
26         public void Dispose()
27         {
28             Dispose(true);
29             GC.SuppressFinalize(this);
30         }
31         ///
32         /// 保存数据DB文件到硬盘
33         ///
34         public void Save()
35         {
36             Redis.Save();
37         }
38         ///
39         /// 异步保存数据DB文件到硬盘
40         ///
41         public void SaveAsync()
42         {
43             Redis.SaveAsync();
44         }
45     }
46 }
RedisOperatorBase 类   HashOperator类,是操作哈希表类。继承自RedisOperatorBase类,代码中有详细注释,理解起来一目了然。





1 using System;
2 using System.Collections.Generic;
3 using ServiceStack.Text;
4
5 namespace RedisDemo.Common.Redis.RedisOperator
6 {
7     public class HashOperator : RedisOperatorBase
8     {
9         public HashOperator() : base() { }
10         ///
11         /// 判断某个数据是否已经被缓存
12         ///
13         public bool Exist(string hashId, string key)
14         {
15             return Redis.HashContainsEntry(hashId, key);
16         }
17         ///
18         /// 存储数据到hash表
19         ///
20         public bool Set(string hashId, string key, T t)
21         {
22             var value = JsonSerializer.SerializeToString(t);
23             return Redis.SetEntryInHash(hashId, key, value);
24         }
25         ///
26         /// 移除hash中的某值
27         ///
28         public bool Remove(string hashId, string key)
29         {
30             return Redis.RemoveEntryFromHash(hashId, key);
31         }
32         ///
33         /// 移除整个hash
34         ///
35         public bool Remove(string key)
36         {
37             return Redis.Remove(key);
38         }
39         ///
40         /// 从hash表获取数据
41         ///
42         public T Get(string hashId, string key)
43         {
44             string value = Redis.GetValueFromHash(hashId, key);
45             return JsonSerializer.DeserializeFromString(value);
46         }
47         ///
48         /// 获取整个hash的数据
49         ///
50         public List GetAll(string hashId)
51         {
52             var result = new List();
53             var list = Redis.GetHashValues(hashId);
54             if (list != null && list.Count > 0)
55             {
56                 list.ForEach(x =>
57                 {
58                     var value = JsonSerializer.DeserializeFromString(x);
59                     result.Add(value);
60                 });
61             }
62             return result;
63         }
64         ///
65         /// 设置缓存过期
66         ///
67         public void SetExpire(string key, DateTime datetime)
68         {
69             Redis.ExpireEntryAt(key, datetime);
70         }
71     }
72 }
HashOperator 类  实战:redis操作hash哈希表的增删改查

  本来打算这部分把我demo中的操作代码贴出来的,想想,全是代码,看着都烦,还不如讲解一下这部分的操作对应于redis客户端操作命令呢。还有一个原因 就是,上面都已经对hash操作进行了分装,其实如果贴代码也就是调用封装的代码罢了。感觉没啥意思,相信大家都会调用。没啥好讲的。那么接下来我就说 下,上面封装的代码与客户端操作的对应关系。
    Exist方法:对应于redis操作的hexists。返回字段是否是 key 指定的哈希集中存在的字段。true:存在  false:不存在
    Set方法:对应于redis操作的hget。设置 key 指定的哈希集中指定字段的值。如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联。如果字段在哈希集中存在,它将被重写。
     Remove(string hashId, string key)方法:对应于redis操作的hdel。从 key 指定的哈希集中移除指定的域。在哈希集中不存在的域将被忽略。如果 key 指定的哈希集不存在,它将被认为是一个空的哈希集,该命令将返回false。
    Remove(string key)方法:对应于redis操作的del。直接删除key。
    Get方法:对应于redis操作的hget。返回该字段所关联的值。
    GetAll方法:对应于redis操作的hvals。获取哈希集中的值的列表,当 key 指定的哈希集不存在时返回空列表。
    SetExpire方法:对应于redis操作的expire。设置缓存过期。
  总结


   
 redis操作很多很多,其实说是封装,也只是封装其中的一些常用操作。有兴趣的朋友可以用反编译工具去看下源码,就可以知道所有操作对应于redis
操作命令了。其实我个人觉得,使用C#操作redis只是语言需要,我们还是要学习它的客户端操作的。开发中,很多时候调试很慢的,我们可以直接通过
redis客户端操作去找,这样效率会更高一点。而且当操作命令熟练的时候,你会发现,客户端操作比调试操作快很多很多。所以,建议大家多多使用客户端操
作。刚开始会感觉很多需要记,熟能生巧,多操作,自然会很好。
    在redis学习过程中,希望大神们能不吝赐教。同时也希望和我一样,在研究路上的同仁,有好的见解或是资料能跟小弟分享下,大家一起探讨学习下。我的QQ联系方式:296319075  随时联系,备注注明园友就好。大家秉承共同探讨、共同进步!如有转载,请注明出处,谢谢!^_^
    还有,如果大家想要源代码的,可以说下,我会把自己用的放到网盘中或者通过QQ等其他方式发给需要的你。  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-88263-1-1.html 上篇帖子: redis 学习指南 下篇帖子: redis windows下的环境搭建
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表