导读
关于Spring Cache以及注解,之前总结了几篇。现在我们再来细化下
概述
注解@Cacheable 和@CachePut 都可以保存缓存键值对,只是它们的方式略有不同, 请注意二者的区别,它们只能运用于有返回值的方法中。
而删除缓存 key 的@CacheEvict 则可以用在 void 的方法上,因为它并不需要去保存任何值 。
上述注解都能标注到类或者方法之上,如果放到类上,则对所有的方法都有效,如果放到方法上,则只是对方法有效。
在大部分情况下,会放置到方法上。 @Cacheable 和 @CachePut 可以配置的属性接近。
一般而言,对于查询,我们会考虑使用@Cacheable
对于插入和修改,考虑使用@CachePut
对于删除操作,我们会考虑使用@CacheEvict。
注解@Cacheable 和@CachePut
因为@Cacheable 和@CachePut 两个注解的配置项 比较接近,所以这里就将这两个注解一并来看
value 和 key 这两个属性使用得最多,所以先来讨论这两个属性。
value 是一个数组,可以引用多个缓存管理器.
案例----->https://blog.csdn.net/yangshangwei/article/details/82961772#Service_664
如上代码所示定义redisCacheManager后就可以引用它了,而对于 key 则是缓存中的键,它支持 Spring 表达式,通过 Spring 表达式就可以自定义缓存的 key。
表达式值的引用
Spring 表达式和缓存注解之间的约定,通过这些约定去引用方法的参数和返回值的内容,使得其注入 key 所定义的 Spring 表达式的结果中。
这样就方便使用对应的参数或者返回值作为缓存的 key 了。
注解@CacheEvict
注解@CacheEvict 主要是为了移除缓存对应的键值对,主要对于那些删除的操作,先来了解它存在哪些属性。
- value 和 key 与之前的@Cacheable 和@CachePut 是一致的。
- 属性 allEntries 要求删除缓存服务器中所有的缓存,这个时候指定的 key 将不会生效,所以这个属性要慎用
- beforeInvocation 属性指定缓存在方法前或者方法后移除。
案例
package com.artisan.ssm_redis.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.artisan.ssm_redis.dao.RoleDao; import com.artisan.ssm_redis.domain.Role; import com.artisan.ssm_redis.service.RoleService; @Service public class RoleServiceImpl implements RoleService { // 自动注入 @Autowired private RoleDao roleDao; /** * 使用@Cacheable定义缓存策略 当缓存中有值,则返回缓存数据,否则访问方法得到数据 通过value引用缓存管理器,通过key定义键 * * @param id * 角色编号 * @return 角色 */ @Override @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED) @Cacheable(value = "redisCacheManager", key = "'redis_role_'+#id") public Role getRole(Long id) { return roleDao.getRole(id); } /** * 使用@CachePut则表示无论如何都会执行方法,最后将方法的返回值再保存到缓存中 * 使用在插入数据的地方,则表示保存到数据库后,会同期插入到Redis缓存中 * * @param role * 角色对象 * @return 角色对象(会回填主键) */ @Override @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED) @CachePut(value = "redisCacheManager", key = "'redis_role_'+#result.id") public Role insertRole(Role role) { roleDao.insertRole(role); return role; } /** * 使用@CachePut,表示更新数据库数据的同时,也会同步更新缓存 * * @param role * 角色对象 * @return 影响条数 */ @Override @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED) @CachePut(value = "redisCacheManager", key = "'redis_role_'+#role.id") public int updateRole(Role role) { return roleDao.updateRole(role); } /** * 使用@CacheEvict删除缓存对应的key * * @param id * 角色编号 * @return 返回删除记录数 */ @Override @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED) @CacheEvict(value = "redisCacheManager", key = "'redis_role_'+#id") public int deleteRole(Long id) { return roleDao.deleteRole(id); } }