根据项目实际情况,需要对某接口数据进行缓存。目前项目使用springboot:v2.2.26。
前期准备
以前一直没用过redis,参考了如下文章:一文搞懂redis,芋道Springboot Redis入门,springboot整合redis。
浏览基础知识后纠正了一个误区,以前以为redis只是内存数据管理,没想到可以持久化到磁盘,而且还有两种方式持久化:快照(RDB文件)和追加式文件(AOF文件)。
1、添加maven依赖
<!-- redis 配置开始 -->
<!-- 实现对 Spring Data Redis 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<!-- 去掉对 Lettuce 的依赖,因为 Spring Boot 优先使用 Lettuce 作为 Redis 客户端 -->
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- 等会示例会使用 fastjson 作为 JSON 序列化的工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!-- Spring Data Redis 默认使用 Jackson 作为 JSON 序列化的工具 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- redis 配置结束 -->
2、配置连接信息
spring:
redis:
host: 192.31.10.44
port: 310
password: # Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码!
database: 1 # Redis 数据库号,默认为 0 。
timeout: 0 # Redis 连接超时时间,单位:毫秒。
# 对应 RedisProperties.Jedis 内部类
jedis:
pool:
max-active: 8 # 连接池最大连接数,默认为 8 。使用负数表示没有限制。
max-idle: 8 # 默认连接数最小空闲的连接数,默认为 8 。使用负数表示没有限制。
min-idle: 0 # 默认连接池最小空闲的连接数,默认为 0 。允许设置 0 和 正数。
max-wait: -1 # 连接池最大阻塞等待时间,单位:毫秒。默认为 -1 ,表示不限制。
设置模板
由于项目中只需要redis的缓存功能,因此只做了string的模板
package com.***.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
/**
* @author steven
*/
@Configuration
public class RedisConfiguration {
/**
* redis模板 key:string value: json
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplateStringJson(RedisConnectionFactory factory) {
// 创建 RedisTemplate 对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 设置开启事务支持
template.setEnableTransactionSupport(true);
// 设置 RedisConnection 工厂。😈 它就是实现多种 Java Redis 客户端接入的秘密工厂。感兴趣的胖友,可以自己去撸下。
template.setConnectionFactory(factory);
// 使用 String 序列化方式,序列化 KEY 。
template.setKeySerializer(RedisSerializer.string());
// 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。
template.setValueSerializer(RedisSerializer.json());
return template;
}
@Bean
public RedisTemplate<String, Object> redisTemplateStringMap(RedisConnectionFactory factory) {
// 创建 RedisTemplate 对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 设置开启事务支持
template.setEnableTransactionSupport(true);
// 设置 RedisConnection 工厂。😈 它就是实现多种 Java Redis 客户端接入的秘密工厂。感兴趣的胖友,可以自己去撸下。
template.setConnectionFactory(factory);
// 使用 String 序列化方式,序列化 KEY 。
template.setKeySerializer(RedisSerializer.string());
// 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。
template.setValueSerializer(RedisSerializer.json());
return template;
}
}
添加工具类
工具类对json统一处理,便于写代码
package com.***.util.Redis;
import com.alibaba.fastjson.JSON;
/**
* JSON 工具类
* @author T490
*/
public class JSONUtil {
public static <T> T parseObject(String text, Class<T> clazz) {
return JSON.parseObject(text, clazz);
}
public static String toJSONString(Object javaObject) {
return JSON.toJSONString(javaObject);
}
public static byte[] toJSONBytes(Object javaObject) {
return JSON.toJSONBytes(javaObject);
}
}
对具体数据处理
按照芋道文章的推荐,把对redis的数据存取放到了DAO层,在Service层中只进行逻辑处理,增强代码的可读性降低维护难度。对每个业务线的缓存都定义key。使用Json工具类明显代码简洁一些。
package com.***.mapper.redis;
import com.***.util.Redis.JSONUtil;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.Map;
/**
* @author steven
*/
@Repository
public class GdbInfoCacheDao {
private static final String KEY_PATTERN = "dataseteId:%s"; // user:数据集id
@Resource(name = "redisTemplateStringJson")
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
private ValueOperations<String, String> operations;
private static String buildKey(String dataseteId) {
return String.format(KEY_PATTERN, dataseteId);
}
public Map get(String dataseteId) {
String key = buildKey(dataseteId);
String value = operations.get(key);
return JSONUtil.parseObject(value, Map.class);
}
public void set(String dataseteId, Map updmInfo) {
String key = buildKey(dataseteId);
String value = JSONUtil.toJSONString(updmInfo);
operations.set(key, value);
}
}
测试结果
注
在使用模板时,需要注入Bean才能编译通过,最开始的时候没有加@Repository类注解,结果编译提示找不到Bean注入失败报:NoSuchBeanDefinitionException错误。