RedisTemplate 两种序列化实践方案
方案一:自定义 RedisTemplate
修改 RedisTemplate 的序列化方式为 GenericJackson2JsonRedisSerializer。
配置类
java
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// 使用 GenericJackson2JsonRedisSerializer 序列化 value
GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
// key 使用 String 序列化
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
// value 使用 JSON 序列化
template.setValueSerializer(jsonSerializer);
template.setHashValueSerializer(jsonSerializer);
template.afterPropertiesSet();
return template;
}
}
使用示例
java
@Service
public class UserService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 写入(自动序列化为 JSON)
public void saveUser(User user) {
redisTemplate.opsForValue().set("user:" + user.getId(), user, 30, TimeUnit.MINUTES);
}
// 读取(自动反序列化为对象)
public User getUser(Long id) {
return (User) redisTemplate.opsForValue().get("user:" + id);
}
}
优缺点
| 优点 | 缺点 |
|---|---|
| 读写无需手动序列化/反序列化 | JSON 中会存储类的全限定名,占用额外空间 |
| 代码简洁 | 类名变更后旧数据无法反序列化 |
| 支持复杂对象类型 | 与其他语言客户端兼容性较差 |
方案二:使用 StringRedisTemplate + 手动序列化
写入时手动将对象序列化为 JSON,读取时手动将 JSON 反序列化为对象。
配置依赖
引入 Jackson(Spring Boot 默认已包含):
xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
使用示例
java
@Service
public class UserService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private ObjectMapper objectMapper;
// 写入:手动序列化为 JSON 字符串
public void saveUser(User user) throws JsonProcessingException {
String json = objectMapper.writeValueAsString(user);
stringRedisTemplate.opsForValue().set("user:" + user.getId(), json, 30, TimeUnit.MINUTES);
}
// 读取:手动反序列化为对象
public User getUser(Long id) throws JsonProcessingException {
String json = stringRedisTemplate.opsForValue().get("user:" + id);
if (json == null) {
return null;
}
return objectMapper.readValue(json, User.class);
}
}
优缺点
| 优点 | 缺点 |
|---|---|
| JSON 数据干净,无多余类型信息 | 每次读写需手动处理序列化 |
| 跨语言兼容性好 | 代码相对繁琐 |
| 数据可读性强,便于调试 | 需要处理 JsonProcessingException |
方案对比总结
| 对比项 | 方案一(自定义 RedisTemplate) | 方案二(StringRedisTemplate) |
|---|---|---|
| 使用便捷性 | 高,自动处理 | 低,手动处理 |
| 存储内容 | 含类型信息的 JSON | 纯净 JSON |
| 跨语言兼容 | 差 | 好 |
| 适用场景 | 纯 Java 项目 | 多语言、对数据格式有要求的项目 |
推荐:对于纯 Java 项目且不需要跨语言访问,优先选择方案一 ;若需要与其他语言共享缓存数据,选择方案二。