Spring Boot之集成Redis(二):集成Redis

作者: 狄仁杰666 | 来源:发表于2020-10-31 11:55 被阅读0次

    前言

    来啦老铁!

    笔者学习Spring Boot有一段时间了,附上Spring Boot系列学习文章,欢迎取阅、赐教:

    1. 5分钟入手Spring Boot;
    2. Spring Boot数据库交互之Spring Data JPA;
    3. Spring Boot数据库交互之Mybatis;
    4. Spring Boot视图技术;
    5. Spring Boot之整合Swagger;
    6. Spring Boot之junit单元测试踩坑;
    7. 如何在Spring Boot中使用TestNG;
    8. Spring Boot之整合logback日志;
    9. Spring Boot之整合Spring Batch:批处理与任务调度;
    10. Spring Boot之整合Spring Security: 访问认证;
    11. Spring Boot之整合Spring Security: 授权管理;
    12. Spring Boot之多数据库源:极简方案;
    13. Spring Boot之使用MongoDB数据库源;
    14. Spring Boot之多线程、异步:@Async;
    15. Spring Boot之前后端分离(一):Vue前端;
    16. Spring Boot之前后端分离(二):后端、前后端集成;
    17. Spring Boot之前后端分离(三):登录、登出、页面认证;
    18. Spring Boot之面向切面编程:Spring AOP;
    19. Spring Boot之集成Redis(一):Redis初入门;

    在上一篇文章Spring Boot之集成Redis(一):Redis初入门中,我们初步入门了Redis,熟悉了Redis的安装、配置、本数据类型以及基本操作。今天,我们一起来尝试在Spring Boot项目中集成Redis,一起在Spring Boot完成一些Redis基本操作吧!

    项目代码已上传Git Hub仓库,欢迎取阅:

    基本步骤

    1. 安装Redis依赖;
    2. 配置application.properties;
    3. 使用StringRedisTemplate操作Redis;

    1. 安装Redis依赖;

    在项目的pom.xml文件内的dependencies节点内添加redis依赖:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
    记得安装一下依赖:
    mvn install -Dmaven.test.skip=true -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true
    

    2. 配置application.properties;

    这里作用主要是配置Redis服务端的连接,配置如下:

    #Redis服务端的host和port
    spring.redis.host=127.0.0.1
    spring.redis.port=6379
    #Redis服务端的密码
    spring.redis.password=Redis!123
    #Redis最大连接数
    spring.redis.pool.max-active=8
    #Redis连接超时时间,单位 ms(毫秒)
    spring.redis.timeout=5000
    

    其中spring.redis.pool.max-active指定了Spring Boot应用的最大连接数,若设置为0,则表示无限制。

    3. 使用StringRedisTemplate操作Redis;

    我的思路是创建一个API,在该API内使用Redis的基本命令,进而演示在Spring Boot项目中与Redis的交互过程。

    (我们先来演示Redis数据类型为String的)

    1). 创建controller包,并在包内创建RedisStringController类;
    2). 创建domain包,并创建实体类RedisStringCache,用于声明Redis String缓存对象格式;

    代码如下:

    package com.github.dylanz666.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.springframework.stereotype.Component;
    
    import java.io.Serializable;
    
    /**
     * @author : dylanz
     * @since : 10/28/2020
     */
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    @Component
    public class RedisStringCache implements Serializable {
        private static final long serialVersionUID = 1L;
    
        private String key;
        private String value;
    
        @Override
        public String toString() {
            return "{" +
                    "\"key\":\"" + key + "\"," +
                    "\"value\":" + value + "" +
                    "}";
        }
    }
    
    3). 在RedisStringController类内添加演示用的API,代码如下:
    package com.github.dylanz666.controller;
    
    import com.github.dylanz666.domain.RedisStringCache;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.web.bind.annotation.*;
    
    /**
     * @author : dylanz
     * @since : 10/28/2020
     */
    @RestController
    @RequestMapping("/api/cache")
    public class RedisStringController {
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
    
        @PostMapping("/string")
        public @ResponseBody RedisStringCache redisStringCache(@RequestBody RedisStringCache redisStringCache) {
            String key = redisStringCache.getKey();
            String value = redisStringCache.getValue();
    
            stringRedisTemplate.opsForValue().set(key, value);
            String cachedValue = stringRedisTemplate.opsForValue().get(key);
    
            RedisStringCache cached = new RedisStringCache();
            cached.setKey(key);
            cached.setValue(cachedValue);
            return cached;
        }
    }
    

    项目整体结构:

    项目整体结构

    上述步骤完成后,我们开始来做演示:

    (1). 启动Redis服务端;
    启动Redis服务端
    (2). 启动Spring Boot应用;
    启动Spring Boot应用
    (3). 调用API进行Redis交互演示;

    请求API:http://127.0.0.1:8080/api/cache/string

    请求API
    (4). 通过redis-cli方式,再次验证是否缓存成功;
    再次验证是否缓存成功

    可见,我们已在Spring Boot项目中与Redis服务端交互成功啦!

    stringRedisTemplate.opsForValue().set(key, value);
    

    上面这一行代码,相当于redis-cli连接Redis服务端方式的 set key value 操作;

    stringRedisTemplate.opsForValue().get(key);
    

    上面这一行代码,相当于redis-cli连接Redis服务端方式的 get key 操作;

    接下来,我们一起来尝试在Spring Boot项目中做更多的Redis基本操作!

    (演示Redis数据类型为hash的)

    1). domain包内创建RedisHashCache实体类,用于声明Redis hash缓存对象格式;
    package com.github.dylanz666.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.springframework.stereotype.Component;
    
    import java.io.Serializable;
    
    /**
     * @author : dylanz
     * @since : 10/28/2020
     */
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    @Component
    public class RedisHashCache implements Serializable {
        private static final long serialVersionUID = 1L;
    
        private String key;
        private String field;
        private String value;
    
        @Override
        public String toString() {
            return "{" +
                    "\"key\":\"" + key + "\"," +
                    "\"field\":\"" + field + "\"," +
                    "\"value\":" + value + "" +
                    "}";
        }
    }
    
    2). RedisStringController内编写演示API:
    @PostMapping("/hash")
    public @ResponseBody RedisHashCache redisHashCache(@RequestBody RedisHashCache redisHashCache) {
        String key = redisHashCache.getKey();
        String field = redisHashCache.getField();
        String value = redisHashCache.getValue();
    
        stringRedisTemplate.opsForHash().put(key, field, value);
        String cachedValue = Objects.requireNonNull(stringRedisTemplate.opsForHash().get(key, field)).toString();
    
        RedisHashCache cached = new RedisHashCache();
        cached.setKey(key);
        cached.setField(field);
        cached.setValue(cachedValue);
        return cached;
    }
    
    stringRedisTemplate.opsForHash().put(key, field, value);
    

    上面这行代码等同于redis-cli中使用命令:hset key field value;

    stringRedisTemplate.opsForHash().get(key, field);
    

    上面这行代码等同于redis-cli中使用命令:hget key field;

    (3). 调用API进行Redis交互演示;

    请求API:http://127.0.0.1:8080/api/cache/hash

    请求API

    (演示Redis数据类型为list的)

    1). domain包内创建RedisListCache实体类,用于声明Redis list缓存对象格式;
    package com.github.dylanz666.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.springframework.stereotype.Component;
    
    import java.io.Serializable;
    import java.util.List;
    
    /**
     * @author : dylanz
     * @since : 10/28/2020
     */
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    @Component
    public class RedisListCache implements Serializable {
        private static final long serialVersionUID = 1L;
    
        private String key;
        private List<String> list;
    
        @Override
        public String toString() {
            return "{" +
                    "\"key\":\"" + key + "\"," +
                    "\"list\":" + list + "" +
                    "}";
        }
    }
    
    2). RedisStringController内编写演示API:
    @PostMapping("/list")
    public @ResponseBody RedisListCache redisListCache(@RequestBody RedisListCache redisListCache) {
        String key = redisListCache.getKey();
        List<String> list = redisListCache.getList();
    
        stringRedisTemplate.opsForList().leftPushAll(key, list);
        List<String> cachedList = stringRedisTemplate.opsForList().range(key, 0, -1);
    
        RedisListCache cached = new RedisListCache();
        cached.setKey(key);
        cached.setList(cachedList);
        return cached;
    }
    
    stringRedisTemplate.opsForList().leftPushAll(key, list);
    

    上面这行代码等同于redis-cli中使用命令:lpush key value...;

    stringRedisTemplate.opsForList().range(key, 0, -1);
    

    上面这行代码等同于redis-cli中使用命令:lrange key 0 -1;

    (3). 调用API进行Redis交互演示;

    请求API:http://127.0.0.1:8080/api/cache/list

    请求API

    (演示Redis数据类型为set的)

    1). domain包内创建RedisSetCache实体类,用于声明Redis set缓存对象格式;
    package com.github.dylanz666.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.springframework.stereotype.Component;
    
    import java.io.Serializable;
    import java.util.Arrays;
    
    /**
     * @author : dylanz
     * @since : 10/28/2020
     */
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    @Component
    public class RedisSetCache implements Serializable {
        private static final long serialVersionUID = 1L;
    
        private String key;
        private String[] sets;
    
        @Override
        public String toString() {
            return "{" +
                    "\"key\":\"" + key + "\"," +
                    "\"sets\":" + Arrays.toString(sets) + "" +
                    "}";
        }
    }
    
    2). RedisStringController内编写演示API:
    @PostMapping("/set")
    public @ResponseBody RedisSetCache redisSetCache(@RequestBody RedisSetCache redisSetCache) {
        String key = redisSetCache.getKey();
        String[] sets = redisSetCache.getSets();
    
        stringRedisTemplate.opsForSet().add(key, sets);
        Set<String> cacheSets = stringRedisTemplate.opsForSet().members(key);
    
        RedisSetCache cached = new RedisSetCache();
        cached.setKey(key);
        assert cacheSets != null;
        cached.setSets(cacheSets.toArray(sets));
        return cached;
    }
    
    stringRedisTemplate.opsForSet().add(key, sets);
    

    上面这行代码等同于redis-cli中使用命令:sadd key value...;

    stringRedisTemplate.opsForSet().members(key);
    

    上面这行代码等同于redis-cli中使用命令:smembers key;

    (3). 调用API进行Redis交互演示;

    请求API:http://127.0.0.1:8080/api/cache/set

    请求API

    (演示Redis数据类型为zset的)

    1). domain包内创建RedisZsetCache实体类,用于声明Redis zset缓存对象格式;
    package com.github.dylanz666.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.springframework.stereotype.Component;
    
    import java.io.Serializable;
    import java.util.Set;
    
    /**
     * @author : dylanz
     * @since : 10/28/2020
     */
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    @Component
    public class RedisZsetCache implements Serializable {
        private static final long serialVersionUID = 1L;
    
        private String key;
        private String value;
        private double score;
        private Set<String> zset;
    
    
        @Override
        public String toString() {
            return "{" +
                    "\"key\":\"" + key + "\"," +
                    "\"value\":\"" + value + "\"," +
                    "\"score\":\"" + score + "\"," +
                    "\"zset\":" + zset + "" +
                    "}";
        }
    }
    
    2). RedisStringController内编写演示API:
    @PostMapping("/zset")
    public @ResponseBody RedisZsetCache redisZsetCache(@RequestBody RedisZsetCache redisZsetCache) {
        String key = redisZsetCache.getKey();
        String value = redisZsetCache.getValue();
        double score = redisZsetCache.getScore();
    
        stringRedisTemplate.opsForZSet().add(key, value, score);
    
        Set<String> cachedZset = stringRedisTemplate.opsForZSet().rangeByScore(key, score, score);
    
        RedisZsetCache cached = new RedisZsetCache();
        cached.setKey(key);
        cached.setValue(value);
        cached.setScore(score);
        cached.setZset(cachedZset);
        return cached;
    }
    
    stringRedisTemplate.opsForZSet().add(key, value, score);
    

    上面这行代码等同于redis-cli中使用命令:zadd key score value;

    stringRedisTemplate.opsForZSet().rangeByScore(key, score, score);
    

    上面这行代码等同于redis-cli中使用命令:zrangebyscore key min max;

    (3). 调用API进行Redis交互演示;

    请求API:http://127.0.0.1:8080/api/cache/zset

    请求API

    最后,来演示设置一个会过期的Redis缓存(演示缓存2分钟):

    @PostMapping("/expire/string")
    public @ResponseBody RedisStringCache redisStringCacheWithExpireTime(@RequestBody RedisStringCache redisStringCache) {
        String key = redisStringCache.getKey();
        String value = redisStringCache.getValue();
    
        stringRedisTemplate.opsForValue().set(key, value, Duration.ofMinutes(2));
        String cachedValue = stringRedisTemplate.opsForValue().get(key);
    
        RedisStringCache cached = new RedisStringCache();
        cached.setKey(key);
        cached.setValue(cachedValue);
        return cached;
    }
    
    缓存2分钟

    通过这样的Redis操作,我们设置了一个2分钟后失效的String类型的Redis缓存,并且的确2分钟后缓存失效了!

    更多操作和redis接口,可直接使用stringRedisTemplate,获取代码建议:
    redis接口

    以上是我们使用StringRedisTemplate来与Redis进行交互的过程,涉及存、取数据,读者可自行根据StringRedisTemplate提供的接口,对Redis进行增删改查。

    实际使用场景中,通常是在第一次存到其他数据库时,会缓存到Redis,并设置一定的缓存过期时间,而后续的请求会先从Redis缓存中获取,减少数据库访问次数,降低数据库服务器的压力!

    使用StringRedisTemplate来与Redis进行交互的过程是正确、灵活的,这一点毋庸置疑,但整体代码还是比较多的,略显臃肿,其实有更简约的方式来操作Redis,这里剧透一下:

    下一篇文章我将介绍基于Spring Cache方式操作Redis,操作Redis缓存也能用注解的方式,敬请期待!

    如果本文对您有帮助,麻烦点赞、关注!

    谢谢!

    相关文章

      网友评论

        本文标题:Spring Boot之集成Redis(二):集成Redis

        本文链接:https://www.haomeiwen.com/subject/sfswmktx.html