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

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

相关推荐
爬山算法6 分钟前
Netty(19)Netty的性能优化手段有哪些?
java·后端
Tony Bai7 分钟前
Cloudflare 2025 年度报告发布——Go 语言再次“屠榜”API 领域,AI 流量激增!
开发语言·人工智能·后端·golang
想用offer打牌20 分钟前
虚拟内存与寻址方式解析(面试版)
java·后端·面试·系统架构
無量24 分钟前
AQS抽象队列同步器原理与应用
后端
五阿哥永琪42 分钟前
RedisTemplate、StringRedisTemplate、RedisIndexedSessionRepository之间的区别?
spring boot
java1234_小锋1 小时前
Redis6为什么引入了多线程?
java·redis
9号达人1 小时前
支付成功订单却没了?MyBatis连接池的坑我踩了
java·后端·面试
用户497357337981 小时前
【轻松掌握通信协议】C#的通信过程与协议实操 | 2024全新
后端
草莓熊Lotso1 小时前
C++11 核心精髓:类新功能、lambda与包装器实战
开发语言·c++·人工智能·经验分享·后端·nginx·asp.net
计算机毕设指导62 小时前
基于微信小程序的鸟博士系统【源码文末联系】
java·spring boot·mysql·微信小程序·小程序·tomcat·maven