Spring Boot中使用@CachePut实现对象列表缓存的增删改操作
你当前的实现是将全量活跃员工列表存入employee缓存区域,要实现增删改操作后同步缓存,可按以下方案实现:
1. 增/改操作的@CachePut实现
@CachePut的作用是将方法返回值写入指定缓存的对应Key,你需要保证更新缓存的Key和查询时的Key完全一致,两种常用实现方式如下:
方式一:保持全量列表缓存(适合列表查询频率高的场景)
首先修改原有查询方法,指定固定Key避免默认生成规则不一致:
@Cacheable(value = "employee", key = "'activeEmployeeList'") public Optional<List<Employee>> employeeData(){ log.info("Fetched employee details from DB and cached in memory!!"); return employeeRepository.findActiveEmployee(); }
新增/更新操作完成后,返回最新的全量列表覆盖缓存:
// 新增员工 @CachePut(value = "employee", key = "'activeEmployeeList'") public Optional<List<Employee>> addEmployee(Employee employee){ employeeRepository.save(employee); return employeeRepository.findActiveEmployee(); } // 更新员工 @CachePut(value = "employee", key = "'activeEmployeeList'") public Optional<List<Employee>> updateEmployee(Employee employee){ employeeRepository.save(employee); return employeeRepository.findActiveEmployee(); }
方式二:按单条员工ID缓存(适合单条操作频率高的场景,性能更优)
拆分缓存粒度,以员工ID为Key存储单条员工数据:
// 单条员工查询 @Cacheable(value = "employee", key = "#id") public Employee getEmployeeById(Long id){ return employeeRepository.findById(id).orElseThrow(() -> new RuntimeException("员工不存在")); } // 新增/更新单条员工,直接写入对应ID的缓存 @CachePut(value = "employee", key = "#employee.id") public Employee saveEmployee(Employee employee){ return employeeRepository.save(employee); }
2. 删除操作实现
删除操作不能用@CachePut,需要搭配@CacheEvict注解清除对应缓存:
// 全量列表缓存场景:删除后清除全量列表缓存,下次查询自动拉取最新数据 @CacheEvict(value = "employee", key = "'activeEmployeeList'") public void deleteEmployee(Long id){ employeeRepository.deleteById(id); } // 单条缓存场景:直接删除对应ID的缓存 @CacheEvict(value = "employee", key = "#id") public void deleteEmployee(Long id){ employeeRepository.deleteById(id); }
3. 按指定条件操作缓存
如果需要满足特定条件才更新/清除缓存,可以使用condition或unless参数配置规则:
// 仅当员工状态为活跃时,才更新缓存 @CachePut(value = "employee", key = "#employee.id", condition = "#employee.active == true") public Employee saveEmployee(Employee employee){ return employeeRepository.save(employee); } // 除非返回结果为空,否则更新全量列表缓存 @CachePut(value = "employee", key = "'activeEmployeeList'", unless = "#result.isEmpty()") public Optional<List<Employee>> updateEmployee(Employee employee){ employeeRepository.save(employee); return employeeRepository.findActiveEmployee(); }
注意:建议先执行DB的增删改操作,再操作缓存,避免DB操作失败但缓存已更新导致的数据不一致问题。
内容的提问来源于stack exchange,提问作者ppb
相关产品推荐
相关产品推荐

