Spring Boot 集成 Redis 连续操作键值对示例
Spring Boot 集成 Redis 连续操作键值对示例
1. 配置 RedisTemplate
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 设置键序列化器(确保键为字符串)
template.setKeySerializer(new StringRedisSerializer());
// 设置值序列化器(支持复杂对象,如JSON)
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
2. Service 层示例代码
@Service
public class RedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 对键 "user:1001" 进行连续操作:
* 1. 设置初始值(User对象)
* 2. 获取值并打印
* 3. 更新值的某个字段
* 4. 设置过期时间
*/
public void performAtomicOperations() {
// 使用 SessionCallback 实现原子性操作
redisTemplate.execute(new SessionCallback<Object>() {
@Override
public Object execute(RedisOperations operations) {
operations.multi(); // 开启事务
// 操作1:设置初始值(User对象)
User user = new User("张三", 25);
operations.opsForValue().set("user:1001", user);
// 操作2:获取值并打印(实际开发中通常不在服务端直接打印)
User fetchedUser = (User) operations.opsForValue().get("user:1001");
System.out.println("获取到的用户:" + fetchedUser.getName());
// 操作3:更新年龄字段(需反序列化后修改)
// 注意:Redis 不支持部分更新,需全量读写
fetchedUser.setAge(26);
operations.opsForValue().set("user:1001", fetchedUser);
// 操作4:设置过期时间
operations.expire("user:1001", 60, TimeUnit.SECONDS);
return operations.exec(); // 提交事务
}
});
}
}
关键代码说明
-
SessionCallback
:- 通过
operations.multi()
开启事务,确保所有操作原子性执行。 - 通过
operations.exec()
提交事务,返回所有操作的结果列表。
- 通过
-
User
对象序列化:- 使用
GenericJackson2JsonRedisSerializer
自动序列化对象为 JSON。 - 需确保
User
类有无参构造函数和getter/setter
。
- 使用
-
更新字段的注意事项:
- Redis 不支持直接更新对象的某个字段,需全量读取-修改-写回。
- 需确保操作在事务中,避免竞态条件。
操作步骤与表格总结
步骤 | 代码片段 | 说明 | 注意事项 |
---|---|---|---|
1. 开启事务 | operations.multi(); | 将后续操作放入事务队列 | 必须在 multi() 和 exec() 之间执行操作 |
2. 设置初始值 | operations.opsForValue().set("user:1001", user); | 存储 User 对象到 Redis | 确保序列化器支持复杂对象 |
3. 获取值 | User fetchedUser = (User) operations.opsForValue().get("user:1001"); | 反序列化 JSON 为对象 | 需强制类型转换 |
4. 更新值 | fetchedUser.setAge(26); operations.opsForValue().set("user:1001", fetchedUser); | 全量更新对象 | 需重新写入整个对象 |
5. 设置过期时间 | operations.expire("user:1001", 60, TimeUnit.SECONDS); | 设置键的过期时间 | 时间单位需明确 |
6. 提交事务 | return operations.exec(); | 执行所有操作并返回结果 | 返回结果为操作结果列表 |
总结与建议
- 原子性操作:通过
SessionCallback
确保多个操作的原子性,避免中间状态暴露。 - 对象更新:Redis 无法部分更新对象,需全量读写,注意性能影响。
- 序列化配置:根据业务需求选择合适的序列化器(如 JSON 或二进制)。
- 错误处理:捕获
RedisException
处理异常,确保事务回滚或重试逻辑。
// 调用示例
@Autowired
private RedisService redisService;
public void test() {
redisService.performAtomicOperations(); // 执行连续操作
}