• spring boot+redis整合基础入门


    前言

    最近项目中有用到redis进行一些数据的缓存,于是就想写一篇springboot集成redis的基础入门,也是给自己留一个可查看的地方,时刻能够提醒自己吧,后续应该会写一下进阶的redis的使用

    准备

    准备上redis的服务,以及搭建一个springboot项目框架,引入依赖

    依赖项

    		
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-data-redisartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    配置文件

    spring:
      redis:
        host: localhost
        port: 6379
        lettuce:
          timeout: 5000 #(连接超时时间,单位为毫秒)
        database: 1
    
    #   集群配置
    #    spring:
    #      redis:
    #        password: 123456  #根据情况而定,看你的redis有没有密码设置
    #        cluster:
    #          nodes: 10.255.144.115:7001,10.255.144.115:7002,10.255.144.115:7003,10.255.144.115:7004,10.255.144.115:7005,10.255.144.115:7006
    #          max-redirects: 3
    
    # 连接池方式
    #spring:
    #  redis:
    #    host: 10.255.144.111
    #    port: 6379
    #    password: 123456
    #    database: 0
    #    lettuce:
    #      pool:
    #        max-idle: 16
    #        max-active: 32
    #        min-idle: 8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    redis模板类注入设置序列化方式

        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
            // 我们为了自己开发方便,一般直接使用 
            RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
            template.setConnectionFactory(connectionFactory);
            // Json序列化配置
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            // String 的序列化
            StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
            // key采用String的序列化方式
            template.setKeySerializer(stringRedisSerializer);
            // hash的key也采用String的序列化方式
            template.setHashKeySerializer(stringRedisSerializer);
            // value序列化方式采用jackson
            template.setValueSerializer(jackson2JsonRedisSerializer);
            // hash的value序列化方式采用jackson
            template.setHashValueSerializer(jackson2JsonRedisSerializer);
            template.afterPropertiesSet();
            return template;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    实施

    基础字符串操作、超时设置

      //String 插入
        @Test
        void contextLoads() {
            String key = "zszxz";
            String value = "知识追寻者";
            redisTemplate.opsForValue().set(key, value);
        }
        // string 读取
        @Test
        public void testForValue(){
            String key = "zszxz";
            Object value = redisTemplate.opsForValue().get(key);
            // 知识追寻者
            System.out.println(value);
        }
        // string key过期时间入库
        @Test
        public void testForValueTimeOut(){
            String key = "today";
            String value = "周六";
            long time = 60;
            redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
        }
        // 测试 key 是否存在
        @Test
        public void testKeyIsExist(){
            String key = "zszxz";
            Boolean exist = redisTemplate.hasKey(key);
            // true
            System.out.println(exist);
        }
        // 设置 key 过期时间
        @Test
        public void testIsTimeOut(){
            String key = "zszxz";
            long time = 60;
            redisTemplate.expire(key, time, TimeUnit.SECONDS);
        }
    
        // 获取key过期时间
        @Test
        public void testGetKeyTimeOut(){
            String key = "zszxz";
            Long expire = redisTemplate.getExpire(key, TimeUnit.SECONDS);
            // 7
            System.out.println(expire);
        }
    
        // 删除key
        @Test
        public void testDeleteKey(){
            String key = "zszxz";
            redisTemplate.delete(key);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    Hash操作

       // 放入一个 hash ( key value )
        @Test
        public void testPushHash(){
            String key = "zszxz";
            String item = "name";
            String value = "知识追寻者";
            redisTemplate.opsForHash().put(key, item, value);
        }
    
        // 向hash中存放一个map
        @Test
        public void testPushMap(){
            String key = "feature";
            Map<String, Object> map = new HashMap<>();
            map.put("name", "知识追寻者");
            map.put("age", "18");
            redisTemplate.opsForHash().putAll(key, map);
        }
    
        // 获取一个hash 的 所有key-value
        @Test
        public void testGekHashAllData(){
            String key = "feature";
            Map<Object, Object> entries = redisTemplate.opsForHash().entries(key);
            // {name=知识追寻者, age=18}
            System.out.println(entries);
        }
    
        // 获取一个hash 的 指定key 的value
        @Test
        public void testGetHashByKey(){
            String key = "feature";
            String item = "name";
            Object value = redisTemplate.opsForHash().get(key, item);
            // 知识追寻者
            System.out.println(value);
        }
    
        // 删除指定 hash key 的value
        @Test
        public void testDeleteHashByKey(){
            String key = "zszxz";
            String item = "name";
            redisTemplate.opsForHash().delete(key, item);
        }
    
        // 是否存在 指定 hash 的key
        @Test
        public void testIsHashKeyExist(){
            String key = "zszxz";
            String item = "name";
            Boolean exist = redisTemplate.opsForHash().hasKey(key, item);
            // false
            System.out.println(exist);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    hash的使用场景以及优缺点

    Redis 中的 Hash 数据类型适用于以下业务场景:

    1. 对象存储:当需要存储和访问复杂对象时,可以将对象的属性作为 Hash 的字段,字段值作为对应属性的值。这样可以将一个完整对象存储在一个 Hash 中,方便操作和管理。

    2. 缓存场景:在缓存中存储一些结构化的数据,例如用户信息、配置项等。通过 Hash 可以有效地组织和管理这些数据,减少缓存键的数量,提高查询效率。

    3. 统计和计数器:使用 Hash 可以方便地存储和更新统计数据和计数器,例如网站的访问次数、文章的点赞数等。通过 Hash 提供的自增和自减操作,可以高效地实现计数功能。

    4. 表示关系:在需要表示关系的场景中,可以将关联关系存储为 Hash 的字段,字段值表示关系的描述或其他附加信息。这样可以清晰地表示不同实体之间的关系。

    Hash 的优点包括:

    • 结构清晰:Hash 存储的数据结构清晰,字段名和字段值之间有明确的映射关系,方便理解和操作。
    • 灵活性高:Hash 可以存储不同类型的字段和值,支持各种复杂的数据结构和对象存储需求。
    • 查询效率高:通过字段名直接访问字段值,查询操作的时间复杂度为 O(1)。

    Hash 的缺点包括:

    • 存储空间占用相对较高:由于每个 Hash 对象都需要存储字段名和字段值的映射关系,因此占用的存储空间较多。
    • 不支持单字段更新:当需要更新 Hash 中的某一个字段时,需要先获取整个 Hash 对象并进行修改,然后再写回数据库。
    • 不适用于大规模数据存储:当 Hash 中的字段数量很多时,操作和维护都会变得复杂,不适合存储大规模的数据。

    列表操作

    // 列表右推入
    @Test
    public void testRightPush(){
        String key = "zszxz";
        String value = "知识追寻者";
        redisTemplate.opsForList().rightPush(key, value);
    }
    
    // 列表左推入
    @Test
    public void testLeftPush(){
        String key = "zszxz";
        String value = "晴雨天";
        redisTemplate.opsForList().leftPush(key, value);
    }
    // 列表左弹出
    @Test
    public void testLeftPop(){
        String key = "zszxz";
        Object value = redisTemplate.opsForList().leftPop(key);
        // 晴雨天
        System.out.println(value);
    
    }
    // 列表右弹出
    @Test
    public void testRightPop(){
        String key = "zszxz";
        Object value = redisTemplate.opsForList().rightPop(key);
        // 知识追寻者
        System.out.println(value);
    }
    
    // 将list右推入列表
    @Test
    public void testListRightPushAll(){
        List<Object> list = new ArrayList<>();
        list.add(12);
        list.add(22);
        list.add(32);
        String key = "number";
        redisTemplate.opsForList().rightPushAll(key, list);
    
        //根据key获取key对应的集合信息
        List<Object> listValue = redisTemplate.opsForList().range(key, 0, -1);
        for (Object o:listValue)
            System.out.println(o);
    }
    
    // 修改列表指定索引的值
    @Test
    public void testUpdateByIndex(){
        String key = "number";
        int index = 0;
        int value = 666;
        redisTemplate.opsForList().set(key, index, value);
    }
    // 获取列表指定索引的值
    @Test
    public void testByIndex(){
        String key = "number";
        int index = 0;
        Object value = redisTemplate.opsForList().index(key, index);
        // 666
        System.out.println(value);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    列表操作的应用场景以及优缺点

    Redis 中的列表数据类型适用于以下业务场景:

    1. 消息队列:通过列表实现消息队列,将任务或消息存储在列表尾部,消费者从列表头部获取任务或消息并进行处理。由于 Redis 提供了多种阻塞式读取列表的方法,因此可以实现高效的异步任务处理和发布订阅功能。

    2. 实时排名:通过列表存储用户访问次数、商品销量等排名信息,使用 Redis 提供的自增和排序操作可以快速地更新和查询排名数据。

    3. 时间轴:通过列表存储和查询时间轴上的事件数据,例如聊天室中的历史消息、微博中的动态等。通过 Redis 提供的切片操作,可以实现按照时间范围查询数据和分页显示等功能。

    4. 历史记录:通过列表存储用户的搜索记录、浏览记录等历史数据,并可以通过 Redis 提供的去重、分页等操作进行查询和展示。

    列表的优点包括:

    • 可以方便地支持队列、栈等多种数据结构。
    • 可以支持快速的随机访问和遍历操作。
    • 无须预先定义长度,支持动态增长和缩容。
    • 支持多种操作,如插入、删除、修剪、合并、排序、查询等。

    列表的缺点包括:

    • 在插入和删除操作频繁的场景中,列表的性能可能会有影响。
    • 在查询和遍历大型列表时,需要消耗大量内存和网络资源。
    • 列表数据无法持久化到磁盘中,重启后数据将被清空。

    Set的基础操作

        // set 中存储值
        @Test
        public void testSetPush(){
            String key = "zszxz";
            String value1 = "晴雨天";
            String value2 = "公众号:知识追寻者";
            redisTemplate.opsForSet().add(key, value1, value2);
        }
    
        // 从 set 中取值
        @Test
        public void testGetValue(){
            String key = "zszxz";
            Set<Object> members = redisTemplate.opsForSet().members(key);
            // [晴雨天, 公众号:知识追寻者]
            System.out.println(members);
        }
    
        // 判定 set 中是否存在 key-value
        @Test
        public void testSetIsExist(){
            String key = "zszxz";
            String value = "晴雨天";
            Boolean member = redisTemplate.opsForSet().isMember(key, value);
            // true
            System.out.println(member);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    Set类型的业务场景以及优缺点

    Redis 中的集合数据类型(Set)适用于以下业务场景:

    1. 标签和分类:使用集合可以方便地管理标签或分类信息。每个元素表示一个标签或分类,可以进行添加、删除、查询等操作,同时还可以计算交集、并集、差集等集合运算。

    2. 好友关系:通过集合可以表示用户之间的好友关系。每个集合表示一个用户的好友列表,可以使用集合操作来实现添加好友、查找共同好友、推荐好友等功能。

    3. 去重:集合中的元素是唯一的,因此可以用于对数据进行去重操作。将需要去重的数据存储在集合中,可以方便地去除重复数据并保留唯一值。

    4. 兴趣爱好:使用集合可以表示用户的兴趣爱好。每个集合表示一个用户的兴趣集合,可以进行集合运算来计算用户之间的相似度或偏好匹配。

    集合的优点包括:

    • 支持快速的元素查找和判断是否存在。
    • 提供了多种集合操作,如并集、交集、差集等,方便对多个集合进行操作和计算。
    • 集合中的元素是唯一的,可以方便地进行去重操作。
    • 集合操作的时间复杂度为 O(n),适用于大规模数据的处理。

    集合的缺点包括:

    • 不支持按照特定顺序排序元素。
    • 集合操作的性能随着元素数量增加而降低,当集合中元素过多时,操作可能会变慢。
    • 集合数据无法持久化到磁盘中,重启后数据将被清空。

    可以使用RedisDesktopManager查看redis中的存储情况
    在这里插入图片描述

    Demo地址

    总结

    对于redis的简单使用springboot已经帮助我们做了集成,给我们封装了很多的api,只要借助提供的api就可以快速入门,但是到入土还需要一些时间。

  • 相关阅读:
    ITSS信息技术服务运行维护标准符合性证书申请详解及流程
    pdf转换器是什么东西?看这篇就懂了!
    Linux(2):初探
    常用工具类Hutool的学习使用
    《Linux驱动:s3c2440 lcd 驱动分析--终结篇》
    Boost研究:Boost Log
    【Vue篇】Vue 项目下载、介绍(详细版)
    【flutter-mobx】Flutter 状态管理- 使用 MobX实现计数器
    css 超出滑动使用 CSS 实现超出滑动
    2024-04-24 问AI: 在深度学习中,CUDA 是什么?
  • 原文地址:https://blog.csdn.net/pengjun_ge/article/details/132864751