redis数据结构的使用场景

数据类型:String、列表List、集合Set、有序集合SortedSet及哈希Hash存储
1.String
字符串很常见,不用多说,当然我们也可以吧一个对象通过ObjectMapper等JSON解析框架进行序列化与反序列化,从而将对象转化为JSON格式的字符串,存起来。

package com.debug.middleware.server;
      //导入包
      import com.debug.middleware.server.entity.Person;
      import com.fasterxml.jackson.databind.ObjectMapper;
      import org.junit.Test;
      import org.junit.runner.RunWith;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.context.SpringBootTest;
      import org.springframework.data.redis.core.RedisTemplate;
      import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
      //单元测试类
      @RunWith(SpringJUnit4ClassRunner.class)
      @SpringBootTest
      public class RedisTest2 {
          //定义日志
          private static final Logger log= LoggerFactory.getLogger(RedisTest2.
      class);
          //定义RedisTemplate操作组件
          @Autowired
          private RedisTemplate redisTemplate;
          //JSON序列化与反序列化框架类
          @Autowired
          private ObjectMapper objectMapper;
          //单元测试方法
          @Test
          public void one() throws Exception{
            //构造用户个人实体对象
            Person p=new Person(10013,23, "修罗", "debug", "火星");
            //定义key与即将存入缓存中的value
            final String key="redis:test:1";
            String value=objectMapper.writeValueAsString(p);
            //写入缓存中
            log.info("存入缓存中的用户实体对象信息为:{} ", p);
            redisTemplate.opsForValue().set(key, value);
            //从缓存中获取用户实体信息
            Object res=redisTemplate.opsForValue().get(key);
            if (res! =null){
                Person resP=objectMapper.readValue(res.toString(), Person.class);
                log.info("从缓存中读取信息:{} ", resP);
            }
          }
      }

2. 列表
Redis的列表类型跟Java的List类型很类似,用于存储一系列具有相同类型的数据。其底层对于数据的存储和读取可以理解为一个“数据队列”。
在Spring Boot整合Redis的项目使用List类型存储数据时,可以通过push添加、pop获取等操作存储获取的数据。在实际应用场景中,Redis的列表List类型特别适用于 “排名” “排行榜” “近期访问数据列表” 等业务场景,是一种很实用的存储类型。

//列表类型
 @Test
 public void two() throws Exception{
     //构造已经排好序的用户对象列表
     List<Person> list=new ArrayList<>();
     list.add(new Person(1,21, "修罗", "debug", "火星"));
     list.add(new Person(2,22, "大圣", "jack", "水帘洞"));
     list.add(new Person(3,23, "盘古", "Lee", "上古"));
     log.info("构造已经排好序的用户对象列表: {} ", list);
     //将列表数据存储至Redis的List中
     final String key="redis:test:2";
     ListOperations listOperations=redisTemplate.opsForList();
     for (Person p:list){
         //往列表中添加数据—从队尾中添加
         listOperations.leftPush(key, p);
     }
     //获取Redis中List的数据—从队头中遍历获取,直到没有元素为止
     log.info("--获取Redis中List的数据-从队头中获取--");
     Object res=listOperations.rightPop(key);
     Person resP;
     while (res! =null){
         resP= (Person) res;
         log.info("当前数据:{} ", resP);
         res=listOperations.rightPop(key);
     }
 }

3.集合
用于存储具有相同类型或特性的不重复的数据。即Redis中的集合Set存储的数据是唯一的,其底层的数据结构是通过哈希表来实现的,所以其添加、删除、查找操作的复杂度均为O(1)。
Redis的集合类型确实可以保证存储的数据是唯一、不重复的。在实际互联网应用中,Redis的Set类型常用于解决重复提交、剔除重复 ID等业务场景

//集合类型
@Test
public void three() throws Exception{
   //构造一组用户姓名列表
   List<String> userList=new ArrayList<>();
   userList.add("debug");
   userList.add("jack");
   userList.add("修罗");
   userList.add("大圣");
   userList.add("debug");
   userList.add("jack");
   userList.add("steadyheart");
   userList.add("修罗");
   userList.add("大圣");
   log.info("待处理的用户姓名列表:{} ", userList);
   //遍历访问,剔除相同姓名的用户并塞入集合中,最终存入缓存中
   final String key="redis:test:3";
   SetOperations setOperations=redisTemplate.opsForSet();
   for (String str:userList){
     setOperations.add(key, str);
   }
   //从缓存中获取用户对象集合
   Object res=setOperations.pop(key);
   while (res! =null){
     log.info("从缓存中获取的用户集合-当前用户:{} ", res);
     res=setOperations.pop(key);
   }
}

4. 有序集合
SortedSet可以通过底层的Score(分数/权重)值对数据进行排序,实现存储的集合数据既不重复又有序,可以说其包含了列表List、集合Set的特性。
Redis的有序集合类型SortedSet确实可以实现数据元素的有序排列。默认情况下,SortedSet的排序类型是根据得分Score参数的取值从小到大排序,如果需要倒序排列,则可以调用reverseRange()方法即可!

//有序集合
        @Test
        public void four() throws Exception{
            //构造一组无序的用户手机充值对象列表
            List<PhoneUser> list=new ArrayList<>();
            list.add(new PhoneUser("103",130.0));
            list.add(new PhoneUser("101",120.0));
            list.add(new PhoneUser("102",80.0));
            list.add(new PhoneUser("105",70.0));
            list.add(new PhoneUser("106",50.0));
            list.add(new PhoneUser("104",150.0));
            log.info("构造一组无序的用户手机充值对象列表:{}", list);
            //遍历访问充值对象列表,将信息塞入Redis的有序集合中
            final String key="redis:test:4";
            //因为zSet在add元素进入缓存后,下次就不能进行更新了,因而为了测试方便
            //进行操作之前先清空该缓存(实际生产环境中不建议这么使用)
            redisTemplate.delete(key);
         //获取有序集合SortedSet操作组件ZSetOperations
            ZSetOperations zSetOperations=redisTemplate.opsForZSet();
            for (PhoneUser u:list){
            //将元素添加进有序集合SortedSet中
              zSetOperations.add(key, u, u.getFare());
            }
            //前端获取访问充值排名靠前的用户列表
            Long size=zSetOperations.size(key);
            //从小到大排序
            Set<PhoneUser> resSet=zSetOperations.range(key,0L, size);
            //从大到小排序
            //Set<PhoneUser> resSet=zSetOperations.reverseRange(key,0L, size);
         //遍历获取有序集合中的元素
            for (PhoneUser u:resSet){
              log.info("从缓存中读取手机充值记录排序列表,当前记录:{} ",u);
          }
        }

5. 哈希Hash存储
Redis的哈希存储跟Java的HashMap数据类型有点类似,其底层数据结构是由Key-Value组成的映射表,而其Value又是由Filed-Value对构成,特别适用于具有映射关系的数据对象的存储。
在实际互联网应用,当需要存入缓存中的对象信息具有某种共性时,为了减少缓存中Key的数量,应考虑采用Hash哈希存储。

/Hash哈希存储
        @Test
        public void five() throws Exception{
            //构造学生对象列表和水果对象列表
            List<Student> students=new ArrayList<>();
            List<Fruit> fruits=new ArrayList<>();
            //往学生集合中添加学生对象
            students.add(new Student("10010", "debug", "大圣"));
            students.add(new Student("10011", "jack", "修罗"));
            students.add(new Student("10012", "sam", "上古"));
            //往水果集合中添加水果对象
              fruits.add(new Fruit("apple","红色"));
              fruits.add(new Fruit("orange","橙色"));
              fruits.add(new Fruit("banana","黄色"));
              //分别遍历不同的对象列表,并采用Hash哈希存储至缓存中
              final String sKey="redis:test:5";
              final String fKey="redis:test:6";
              //获取Hash存储操作组件HashOperations,遍历获取集合中的对象并添加进缓存中
              HashOperations hashOperations=redisTemplate.opsForHash();
              for (Student s:students){
                  hashOperations.put(sKey,s.getId(),s);
              }
              for (Fruit f:fruits){
                  hashOperations.put(fKey,f.getName(),f);
              }
              //获取学生对象列表与水果对象列表
              Map<String,Student> sMap=hashOperations.entries(sKey);
              log.info("获取学生对象列表:{} ",sMap);
              Map<String,Fruit> fMap=hashOperations.entries(fKey);
              log.info("获取水果对象列表:{} ",fMap);
              //获取指定的学生对象
              String sField="10012";
              Student s= (Student) hashOperations.get(sKey,sField);
              log.info("获取指定的学生对象:{} -> {} ",sField,s);
            //获取指定的水果对象
              String fField="orange";
              Fruit f= (Fruit) hashOperations.get(fKey,fField);
              log.info("获取指定的水果对象:{} -> {} ",fField,f);
           }

猜你喜欢

转载自blog.csdn.net/weixin_43978695/article/details/111054966