redis官网提供了很多开源的C#客户端。其中ServiceStack.Redis应该算是比较流行的。它提供了一整套从Redis数据结构的强数据类型转换的机制并将对象json序列化。
ServiceStack.Redis地址:https://github.com/ServiceStack/ServiceStack.Redis
1 string类型操作
strings类型是最常用的数据类型,在redis中以key-value存储。
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public override string ToString()
{
return $"Id:{Id},Name:{Name},Age:{Age}";
}
}
class Program
{
static void Main(string[] args)
{
//创建客户端,注意有密码的需要传入密码。密码可以从配置文件中获取。
RedisClient redis = new RedisClient("127.0.0.1", 6379, "123456");
Person p1 = new Person { Age = 18, Name = "zhuangjuan", Id = 000 };
Person p2 = new Person { Age = 19, Name = "zhudaokuan", Id = 001 };
Person p3 = new Person { Age = 20, Name = "wangmazi", Id = 002 };
#region String数据结构的操作,注意这里的string类型不是说我们的数据类型,而是数据库中的数据结构
//清空数据库
redis.FlushDb();
//修改数据,如果key不存在则是添加数据
//这里的泛型类型 其实会被序列化为json存储到数据库中.
Console.WriteLine(redis.Set<Person>("p1", p1));
//获取当前key的数据结构类型.总共定义了5大类型.
RedisKeyType type = redis.GetEntryType("p1");
Console.WriteLine(type.ToString());
//设置过期时间
Console.WriteLine(redis.Set<Person>("p1", p1, DateTime.Now.AddDays(1)));
Console.WriteLine(redis.Set<Person>("p1", p1, new TimeSpan(24, 0, 0)));
//读取数据,如果key不存在则返回""
//从数据库中读到的json对象,会被反序列化为泛型类型对象.
Console.WriteLine(redis.Get<Person>("p1").ToString());
//删除数据,
Console.WriteLine(redis.Remove("p1"));
//批量操作数据
Dictionary<string, Person> dic = new Dictionary<string, Person>()
{
{ "p1",p1},
{ "p2",p2},
{ "p3",p3},
};
redis.SetAll<Person>(dic);
redis.GetAll<Person>(new string[] { "p1", "p2", "p3" });
redis.RemoveAll(new string[] { "p1", "p2", "p3" });
#endregion
}
}
2 Hash类型操作
Hash在redis中采用(HashId,key,value)进行存储。一个HashId可以包含多个不相同的key,一个key对应着一个value。所以Hash类型可以看作是String类型的集合,HashId可以理解为集合的名称。
#region hash数据结构的操作
redis.FlushDb();
redis.SetEntryInHash("hash1", "p1", JsonSerializer.Serialize(p1));
redis.SetEntryInHash("hash1", "p2", JsonSerializer.Serialize(p1));
redis.SetEntryInHash("hash1", "p3", JsonSerializer.Serialize(p1));
Person p = JsonSerializer.Deserialize<Person>(redis.GetValueFromHash("hash1", "p1"));
#endregion
3 List类型操作
List类型在redis中是按照(listId,value)来存储的,每一个value会自动生成一个对应的序号。List中可以有相同的value。
#region List数据类型的操作
redis.PushItemToList("list1", JsonSerializer.Serialize(p1));
redis.PushItemToList("list1", JsonSerializer.Serialize(p2));
redis.PushItemToList("list1", JsonSerializer.Serialize(p3));
redis.PushItemToList("list1", JsonSerializer.Serialize(p3));
redis.GetAllItemsFromList("list1");
#endregion
4 set类型操作
set类型和list类型类似,唯一不同的是,set类型中不会存储相同value的数据。
#region set数据类型的操作()
redis.AddItemToSet("set1", JsonSerializer.Serialize(p1));
redis.AddItemToSet("set1", JsonSerializer.Serialize(p2));
redis.AddItemToSet("set1", JsonSerializer.Serialize(p3));
redis.AddItemToSet("set1", JsonSerializer.Serialize(p3));//有相同的value,会被自动剔除掉.
var items = redis.GetAllItemsFromSet("set1");
#endregion
5 zset类型操作
zset在redis中按照(setId,value,score)存储,score参数用来排序。zset类型与set类型也类似,唯一不同的是,zset会自动排序。
#endregion
#region zset数据类型的操作--去重的自动排序的链表
redis.AddItemToSortedSet("zset1", JsonSerializer.Serialize(p2), p2.Id);
redis.AddItemToSortedSet("zset1", JsonSerializer.Serialize(p3), p3.Id);
redis.AddItemToSortedSet("zset1", JsonSerializer.Serialize(p1), p1.Id);
#endregion
6 连接池
在我们实际的使用Redis的过程中,肯定不能在每个调用的类都实例化RedisClient来直接使用,这样太麻烦,还涉及到相关异常情况处理,一般是将操作Redis的相关方法封装成通用的工具类,提供给调用方使用。
public class RedisCacheHelper
{
private static readonly PooledRedisClientManager pool = null;
private static readonly string redisHosts = "123456@127.0.0.1:6379";
public static int RedisMaxReadPool = 3;
public static int RedisMaxWritePool = 1;
static RedisCacheHelper()
{
pool = new PooledRedisClientManager(new string[] { redisHosts }, new string[] { redisHosts }, new RedisClientManagerConfig()
{
MaxReadPoolSize = RedisMaxReadPool,
MaxWritePoolSize = RedisMaxWritePool,
AutoStart = true,
});
}
}
首先我们创建了一个工具类,在这里使用到了池的概念。其中有一个连接字符串可以注意一下,关于服务器的配置参数我们可以使用配置文件,这里就简便处理了。
localhost
127.0.0.1:6379
redis://localhost:6379
password@localhost:6379
clientid:password@localhost:6379
redis://clientid:password@localhost:6380?ssl=true&db=1
连接池在使用得时候需要在池中获取一个客户端。
using (IRedisClient redis = pool.GetClient())
{
//do something
}