Spring Boot 集成 Redis中@Cacheable 和 @CachePut 的详细对比,涵盖功能、执行流程、适用场景、参数配置及代码示例

以下是 @Cacheable@CachePut 的详细对比,涵盖功能、执行流程、适用场景、参数配置及代码示例:


1. 核心对比表格

特性 @Cacheable @CachePut
作用 缓存方法的返回结果,避免重复计算 执行方法并更新缓存,不覆盖原有缓存
执行流程 缓存命中 :直接返回缓存值,不执行方法 未命中:执行方法,缓存结果 始终执行方法,并将结果更新到缓存
适用场景 查询操作(如get方法) 更新操作(如saveupdate方法)
缓存行为 覆盖原有缓存值(或按条件更新) 追加或覆盖缓存值(不删除原有数据)
是否执行方法 仅当缓存未命中时执行 始终执行方法
性能影响 最优(减少重复计算) 稍高(需同时执行方法和更新缓存)

2. 详细对比说明

(1) @Cacheable
  • 核心功能:根据方法参数生成缓存键(key),若缓存中存在对应键的值,则直接返回缓存值,否则执行方法并将结果存入缓存。
  • 适用场景:查询操作(如从数据库或远程服务获取数据)。
  • 参数配置
    • value/cacheNames:指定缓存名称(必填)。
    • key:自定义缓存键(如#id)。
    • condition:条件判断是否缓存(如#result != null)。
    • unless:条件判断是否不缓存(如#result == null)。
(2) @CachePut
  • 核心功能 :无论缓存是否存在,始终执行方法,并将方法结果更新到缓存中。
  • 适用场景:更新操作(如保存或更新数据后同步更新缓存)。
  • 参数配置
    • value/cacheNames:指定缓存名称(必填)。
    • key:自定义缓存键(如#user.id)。
    • condition/unless:控制是否更新缓存。

3. 代码示例对比

场景:用户信息的增删改查
java 复制代码
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    // @Cacheable:缓存查询结果
    @Cacheable(value = "userCache", key = "#id")
    public User getUserById(Long id) {
        System.out.println("从数据库查询用户ID:" + id);
        return userMapper.selectUserById(id);
    }

    // @CachePut:更新缓存(同时更新数据库)
    @CachePut(value = "userCache", key = "#user.id")
    public User updateUser(User user) {
        System.out.println("更新用户信息并缓存:ID=" + user.getId());
        userMapper.updateUser(user); // 更新数据库
        return user;
    }
}
执行流程对比
方法 @Cacheable流程 @CachePut流程
getUserById(1) 1. 检查userCache:1是否存在 2. 存在则返回缓存,不执行方法 3. 不存在则执行方法并缓存结果 不适用
updateUser(user) 不适用 1. 始终执行方法 (更新数据库) 2. 将返回结果存入userCache:user.id

4. 关键参数对比

@Cacheable
参数 描述 示例值
value 缓存名称(必填) "userCache"
key 缓存键(默认#method.name + #root.args "user_" + #id
condition 只有满足条件时才缓存结果 #result != null
unless 满足条件时不缓存结果 #result.age < 18
@CachePut
参数 描述 示例值
value 缓存名称(必填) "userCache"
key 缓存键(默认#method.name + #root.args "user_" + #user.id
condition 只有满足条件时才更新缓存 #user.name != null

5. 注意事项

  1. 组合使用场景

    • 更新操作 :通常需要@CachePut@CacheEvict的组合,例如:

      java 复制代码
      @CacheEvict(value = "userCache", key = "#id") // 先删除旧缓存
      @CachePut(value = "userCache", key = "#user.id") // 再存入新数据
      public User updateUser(User user, Long id) { ... }
    • 新增操作 :使用@CachePut将新数据存入缓存(如insertUser方法)。

  2. 缓存一致性

    • 对于更新操作,需确保数据库和缓存同时更新,避免数据不一致。
    • 使用@CacheEvict清除旧缓存,再通过@CachePut存入新数据。
  3. 性能权衡

    • @CachePut会强制执行方法,需评估是否影响性能。
    • 对于高频写操作,需结合缓存过期策略(如time-to-live)。

6. 总结表格

注解 作用 是否执行方法 适用场景 关键参数
@Cacheable 缓存方法结果,减少重复计算 仅当缓存未命中时执行 查询操作(get value, key, condition
@CachePut 更新缓存,确保数据一致性 始终执行方法 更新操作(updatesave value, key, condition

通过以上对比,可以清晰理解这两个注解的差异和使用场景,从而在实际开发中合理选择和组合使用。

相关推荐
椰椰椰耶40 分钟前
【Spring】拦截器详解
java·后端·spring
brzhang2 小时前
我操,终于有人把 AI 大佬们 PUA 程序员的套路给讲明白了!
前端·后端·架构
G_whang4 小时前
jenkins使用Jenkinsfile部署springboot+docker项目
spring boot·docker·jenkins
wan_da_ren4 小时前
JVM监控及诊断工具-GUI篇
java·开发语言·jvm·后端
【本人】4 小时前
Django基础(一)———创建与启动
后端·python·django
lifallen4 小时前
Kafka 时间轮深度解析:如何O(1)处理定时任务
java·数据结构·分布式·后端·算法·kafka
你的人类朋友5 小时前
【✈️速通】什么是SIT,什么是UAT?
后端·单元测试·测试
程序无bug7 小时前
后端3行代码写出8个接口!
java·后端
绝无仅有7 小时前
使用LNMP一键安装包安装PHP、Nginx、Redis、Swoole、OPcache
后端·面试·github
他日若遂凌云志7 小时前
C++ 与 Lua 交互全链路解析:基于Lua5.4.8的源码剖析
后端