spring-cache集成redis

在Spring-boot集成Redis基础上,集成spring-cache
Spring-boot集成Redis

1、RedisConfig 类添加注解 @EnableCaching
在这里插入图片描述
2、keyGenerator

    /**
     * 自定义缓存的key
     * @return
     */
    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator(){
            @Override
            public Object generate(Object target, Method method, Object... params){
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName()).append(".");
                sb.append(method.getName()).append(".");
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                System.out.println("keyGenerator="+sb.toString());
                return sb.toString();
            }
        };
    }

3、cacheManager

    /**
     * 创建RedisCacheManager
     * @param connectionFactory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory){
        //初始化一个RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
        //设置CacheManager的值序列化方式
        //RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
        //设置默认超过期时间是30秒
        defaultCacheConfig.entryTtl(Duration.ofSeconds(30));
        //初始化RedisCacheManager
        RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
        return redisCacheManager;
    }

4、方法中添加注解

    /**
     * 保存缓存
     * @param id
     * @return
     */
    @Cacheable(value = "log", key = "'log'.concat(#id.toString())")
    public Log findLogById(Long id) {
        String sql = "select id,content,createtime from log_info where id = ?";
        RowMapper<Log> rowMapper = new BeanPropertyRowMapper<>(Log.class);
        Log log = jdbcTemplate.queryForObject(sql,rowMapper,id);
        System.out.println("log="+log);
        return log;
    }

    /**
     * 重新保存缓存
     * @param log
     * @return
     */
    @CachePut(value = "log", key = "'log'.concat(#log.id.toString())")
    public Log update(Log log) {
        Integer id = log.getId();
        String content = "测试缓存"+id;
        log.setContent(content);
        jdbcTemplate.update("UPDATE log_info SET content = ? WHERE id = ?", new Object[] {content, id});
        System.out.println("log="+log);
        return log;
    }

    /**
     * 删除缓存
     * @param id
     */
    @CacheEvict(value = "log", key = "'log'.concat(#id.toString())")
    public void remove(Long id) {
        String sql = "delete from log_info where id=?";
        int update = jdbcTemplate.update(sql, id);
        System.out.println(update);
    }

5、注解描述

@Cacheable     触发缓存入口
一般用于查询操作,根据key查询缓存.
 1. 如果key不存在,查询db,并将结果更新到缓存中。
 2. 如果key存在,直接查询缓存中的数据。

@CacheEvict    触发移出缓存
根据key删除缓存中的数据。allEntries=true表示删除缓存中的所有数据。

@CachePut      触发更新缓存
 一般用于更新和插入操作,每次都会请求db
 1. 如果key存在,更新内容
 2. 如果key不存在,插入内容。

 @Caching       将多种缓存操作分组
 这个注解将其他注解方式融合在一起了,我们可以根据需求来自定义注解,并将前面三个注解应用在一起

 @CacheConfig   类级别的缓存注解,允许共享缓存名称
 该注解是可以将缓存分类,它是类级别的注解方式。

6、自定义AOP缓存
自定义注解

/**
 * 元注解 用来标识查询数据库的方法
 */
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RedisCache {

}

自定义Aspect

/**
 * AOP实现Redis缓存处理
 */
@Component
@Aspect
public class RedisAspect {

    @Autowired
    private RedisService redisService;

    /**
     * 拦截所有元注解RedisCache注解的方法
     */
    @Pointcut("@annotation(com.seata.business.annotation.RedisCache)")
    public void pointcutMethod(){

    }

    /**
     * 环绕处理,先从Redis里获取缓存,查询不到,就查询MySQL数据库,
     * 然后再保存到Redis缓存里
     * @param joinPoint
     * @return
     */
    @Around("pointcutMethod()")
    public Object around(ProceedingJoinPoint joinPoint){
        //前置:从Redis里获取缓存
        //先获取目标方法参数
        long startTime = System.currentTimeMillis();
        String applId = null;
        Object[] args = joinPoint.getArgs();
        if (args != null && args.length > 0) {
            applId = String.valueOf(args[0]);
        }
        //获取目标方法所在类
        String target = joinPoint.getTarget().toString();
        String className = target.split("@")[0];
        //获取目标方法的方法名称
        String methodName = joinPoint.getSignature().getName();
        //redis中key格式:    applId:方法名称
        String redisKey = applId + ":" + className + "." + methodName;
        Object obj = redisService.getCacheObject(redisKey);
        if(obj!=null){
            System.out.println("**********从Redis中查到了数据**********");
            System.out.println("Redis的KEY值:"+redisKey);
            System.out.println("Redis的VALUE值:"+obj.toString());
            return obj;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("Redis缓存AOP处理所用时间:"+(endTime-startTime));
        System.out.println("**********没有从Redis查到数据**********");
        try{
            obj = joinPoint.proceed();
        }catch(Throwable e){
            e.printStackTrace();
        }
        System.out.println("**********开始从MySQL查询数据**********");
        //后置:将数据库查到的数据保存到Redis
        redisService.setCacheObject(redisKey,obj);
        if(redisService.hasKey(redisKey)){
            System.out.println("**********数据成功保存到Redis缓存!!!**********");
            System.out.println("Redis的KEY值:"+redisKey);
            System.out.println("Redis的VALUE值:"+obj.toString());
        }
        return obj;
    }

    /**
     * 增删改操作会先将对应的缓存从redis中删除
     * 再重新查询数据库并重新存入redis缓存
     * @param joinPoint
     */
    @After("execution(* com.seata.business.service.*.*(..)) && !execution(* com.seata.business.service.*.select*(..))&& !execution(* com.seata.business.service.*.find*(..))")
    public void after(JoinPoint joinPoint){
        String name = joinPoint.getTarget().getClass().getName();
        redisService.deleteObject(name);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值