背景:系统使用shiro做权限控制,每次调用需要权限的方法时会查询数据库获取该用户的角色进行对比,此查询的频率大于更新频率,所以使用缓存进行优化
配置:
# application.yaml
spring:
redis:
host: redis ip地址
port: redis 端口
cache:
type: redis
1.、使用 @EnableCaching 开启缓存
2.、使用 @Cacheable 注解 给查找所有角色名称方法添加缓存
@Cacheable(value = "roles", key = "T(String).valueOf(#userId)", unless = "#result eq null ") public Collection<String> selectRoleNamesByUserId(Integer userId) { return userRoleMapper.selectRoleNames(userId); }
3.、使用 @CacheEvict 注解 删除缓存(当数据库中的数据进行更新时)
@CacheEvict(value = "roles", key = "T(String).valueOf(#userId)") public void updateRoleByUserIdAndRoleId(Long userId, Long roleId) {
// 以下为业务逻辑,大概意思为更新了数据库中的角色用户关联数据 if(roleId.equals(Constant.USER_ROLE_ID)){ userRoleMapper.updateDriverToUser(userId, Constant.USER_ROLE_ID, Constant.DRIVER_ROLE_ID); }else if(roleId.equals(Constant.DRIVER_ROLE_ID)){ userRoleMapper.updateUserToDriver(userId, Constant.USER_ROLE_ID, Constant.DRIVER_ROLE_ID); } }
@Cacheable注解详解:
注解描述:
* 表明调用一个方法(或所有方法的结果【注解在类上】)可以被缓存
* 每次调用该注解注解的方法时,都会应用缓存行为,默认的key【key值为从缓存中取该缓存value的key】使用方法参数计算秘钥,可以通过该注解的key属性替换默认值
* 如果在缓存中找不到该key值,则该目标的方法会进行调用【就是执行方法体】,将返回的值存储在缓存中。
常用属性描述:
value: 缓存的名称
key: 缓存的key,可以为空,如果指定要按照SpEL表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
condition: 缓存的条件,可以为空,使用SpEL编写,返回为true或false,只有true才进行缓存
unless: 否定缓存,当条件为true时就不会缓存
@CacheEvict注解详解
* 表示方法(或类中的所有方法)执行时根据key值触发缓存清空操作
属性描述
allEntries: 表示是否需要清除缓存中的所有元素,默认为false,如果为true,将忽略该注解指定的key。【将缓存中的元素全部清空,比一个一个清空更加有效】
beforeInvocation: 清除操作默认是在对应方法成功之后触发的,即方法如果因为抛出异常而未能成功返回时不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。
以上三个注解完成了我的需求,其余跟缓存相关注解用到后再添加