ServiceStack.Redis提供了多个Ingerface来操作存储在服务端的数据。有如下几类:
1.IRedisClient:定义了基本的与Redis服务连接的操作方法和属性、hashtable、set、List、sorted list以及键值对的操作方法。主要提供字符串为键值的各种List、Set的操作。
2.IRedisNativeClient:提供了一个原生的、与Redis命令一一对应的接口。
3.IRedisTransaction:提供队列(Queue-UP)事务操作,使得在调用RedisClient的时候都是在一个事务,在操作失败的时候能够回滚整个事务,保证操作的原子性。
4.IRedisTypedClient:提供一个强类型的方法约定,Redis中的值都能够直接操作与C#的值上。
5.IRedisTypedTransaction:与IRedisTransaction类似,区别之处就是所有的值都是强类型的。
在接下来我们将说说如上接口所对应的类的具体使用方法。
(一)Redis Client总览
Redis Client是提供了多个实体类以及多种方法与Redis Server进行交互。
Redis Client的继承关系如下:
RedisTypedClient>RedisClient>RedisNativeClient.
每一个Redis client都提供了不同方法的抽象:
RedisNativeClient:提供了本地的字节操作的方法,
RedisClient:提供字符串的操作方法,(将string转换为字节;采用UTF-8编码)。
RedisTypedClient:提供直接操作具体类的API.能够添加POCO的值(POCO的值采用json serializer序列化,链接地址:https://github.com/ServiceStackV3/mythz_blog/blob/master/pages/344.md)。
Redis client的类图结构如下:
(图片来源:https://github.com/ServiceStack/ServiceStack.Redis)
(二)使用实例
在这节中我将使用redis client做一个简单的学生成绩管理的demo,该demo主要有一下的一些功能:
1.学生、课目以及成绩录入功能:能够添加新的学生、新的课目以及录入学生成绩,当有冲突时,拒绝录入。
2.查询学习成绩:包括个人所有科目、某一科目所有学生成绩。
3.统计功能:能够求出每一科目的平均分,一个班级的前10名等操作。
暂时就实现如上的3个小功能,需要使用到的实体类定义如下:
public class Student { public string StuName { get; set; } public string StuId { get; set; } public string ClassId { get; set; } public override int GetHashCode() { return Convert.ToInt32(StuId); } } public class Class { public string ClassName { get; set; } public string ClassId { get; set; } public string Grade { get; set; } public override int GetHashCode() { return Convert.ToInt32(ClassId); } } public class Course { public string CourseName { get; set; } public string CourseId { get; set; } public override int GetHashCode() { return CourseId.GetHashCode(); } } public class Core { public string courceId { get; set; } public string StuId { get; set; } public double coreNumber { get; set; } }
由于是操作具体的类,所有我们主要是使用RedisTypedClient来添加、删除或者是更新redis server中的数据。我们一般是通过RedisClient的AS<T>()方法来获得具体的RedisTypedClient。如下使用示例:
RedisClient redisClient = new RedisClient("192.168.250.221", 6379);
var redisStudentTypeClient = redisClient.As<Student>();
在获得了具体的RedisTypedClient后,就可以使用RedisTypedClient来操作我们的已经定义好的student、Class、Course等实体类。在这里我们就使用简单的List结构来存储所有的记录。
RedisClient redisClient = new RedisClient("192.168.250.221", 6379); var redisStudentTypeClient = redisClient.As<Student>(); var redisClassTypeClient=redisClient.As<Class>(); var redisCourseTypeClient = redisClient.As<Course>(); redisStudentTypeClient.DeleteAll(); var student1 = new Student() { StuName = "a", StuId = "1", ClassId = "1" }; var student2 = new Student() { StuName = "b", StuId = "2", ClassId = "1" }; var student3 = new Student() { StuName = "a1", StuId = "11", ClassId = "11" }; var student4 = new Student() { StuName = "b1", StuId = "21", ClassId = "11" }; var Classes1=new Class(){ ClassId="1", ClassName="software enginering", Grade="2005" }; var Classes2=new Class(){ ClassId="11", ClassName="software enginering", Grade="2006" }; var course1 = new Course() { CourseName="C++", CourseId="1" }; var ClassList=redisClassTypeClient.Lists["class"]; var studentList = redisStudentTypeClient.Lists["student"]; var courseList = redisCourseTypeClient.Lists["course"]; if(!ClassList.Contains(Classes1)) { ClassList.Add(Classes1); } if(!ClassList.Contains(Classes2)) { ClassList.Add(Classes2); } if (!studentList.Contains(student1)) { studentList.Add(student1); studentList.Add(student2); studentList.Add(student3); studentList.Add(student4); } if (!courseList.Contains(course1)) { courseList.Add(course1); } redisClient.StoreAll(ClassList); redisClient.StoreAll(studentList); redisClient.StoreAll(courseList);
在示例中我们使用RedisTypedClient的Lists属性来获取我们需要存储的IRedisList,我们在获取的时候如果IRedisList不存在,ServiceStack.RedisClient会创建一个新的IRedisList。
var ClassList=redisClassTypeClient.Lists["class"];
var studentList = redisStudentTypeClient.Lists["student"];
var courseList = redisCourseTypeClient.Lists["course"];
IRedisList提供了Add、Remove、Trime等操作,实现的功能与.Net Framework中的泛型List的功能是类似的。提供的方法如下:
void AddRange(IEnumerable<T> values); void Append(T value); T BlockingDequeue(TimeSpan? timeOut); T BlockingPop(TimeSpan? timeOut); T BlockingRemoveStart(TimeSpan? timeOut); T Dequeue(); void Enqueue(T value); List<T> GetAll(); List<T> GetRange(int startingFrom, int endingAt); List<T> GetRangeFromSortedList(int startingFrom, int endingAt); T Pop(); T PopAndPush(IRedisList<T> toList); void Prepend(T value); void Push(T value); void RemoveAll(); T RemoveEnd(); T RemoveStart(); long RemoveValue(T value); long RemoveValue(T value, int noOfMatches); void Trim(int keepStartingFrom, int keepEndingAt);
在使用IRedisList集合添加或者其他操作后,我们需要使用RedisTypedClient的store方法将所IRedisList进行保存到服务器中;RedisTypedClient方法提供多个以Store开头的方法来将client端的数据提交到server端。与Store方法对应的就是Get方法,RedisTypedClient类提供了多种Get开头的方法用于获取Server端的数据。
我们在这里主要学习了IRedisList和RedisTypedClient的使用方法,讲述了Redis client中提供的类的简单用法。Redis client中除了IRedisList外还提供了其他的泛型集合的使用方法,我们在后面章节中会一一使用到。