• springboot与redis整合 @Cacheable 的使用


    首先我们需要配置一个缓存管理器,然后才能使用缓存注解来管理缓存

    package com.cherish.servicebase.handler;
    
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializationContext;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    import java.time.Duration;
    
    @Configuration
    @EnableCaching
    public class RedisConfig extends CachingConfigurerSupport {
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            RedisSerializer<String> redisSerializer = new StringRedisSerializer();
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            template.setConnectionFactory(factory);
            //key序列化方式
            template.setKeySerializer(redisSerializer);
            //value序列化
            template.setValueSerializer(jackson2JsonRedisSerializer);
            //value hashmap序列化
            template.setHashValueSerializer(jackson2JsonRedisSerializer);
            return template;
        }
    
        @Bean
        public CacheManager cacheManager(RedisConnectionFactory factory) {
            RedisSerializer<String> redisSerializer = new StringRedisSerializer();
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            //解决查询缓存转换异常的问题
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            // 配置序列化(解决乱码的问题),过期时间600秒
            RedisCacheConfiguration config = RedisCacheConfiguration
                    .defaultCacheConfig()
                    .entryTtl(Duration.ofSeconds(600))
                    .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                    .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                    .disableCachingNullValues();
    
            RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                    .cacheDefaults(config)
                 // 可以给每个cacheName不同的RedisCacheConfiguration  设置不同的过期时间
                //.withCacheConfiguration("Users",config.entryTtl(Duration.ofSeconds(100)))
                    .transactionAware()
                    .build();
            return cacheManager;
        }
    }
    
    

    1、@Cacheable

    标记在方法或者类上,标识该方法或类支持缓存。Spring调用注解标识方法后会将返回值缓存到redis,以保证下次同条件调用该方法时直接从缓存中获取返回值。这样就不需要再重新执行该方法的业务处理过程,提高效率。

    @Cacheable常用的三个参数如下:

    cacheNames 缓存名称
    key 缓存的key,需要注意key的写法哈
    condition 缓存执行的条件,返回true时候执行

    示例

        //查询所有用户,缓存到redis中
        @GetMapping("/selectFromRedis")
        @Cacheable(cacheNames = "Users",key = "'user'")
        public ResultData getUserRedis(){
            List<User> list = userService.list(null);
            return ResultData.ok().data("User",list);
        }
    

    image-20210603220328748

    第一次查询是从数据库查询的,然后缓存到redis中 使用redis可视化工具查看缓存的信息

    image-20210603222417987

    第二查询走了缓存控制台没有输出 ,所以走的redis缓存 就是在redis中获取结果直接返回。

    image-20210603220951931

    @CacheEvict

    标记在方法上,方法执行完毕之后根据条件或key删除对应的缓存。常用的属性:

    • allEntries boolean类型,表示是否需要清除缓存中的所有元素
    • key 需要删除的缓存的key
     //调用这个接口结束后,删除指定的Redis缓存
        @PostMapping("updateUser")
        @CacheEvict(cacheNames ="Users",key = "'user'")
        public ResultData updateUser(@RequestBody User user){
            String id = user.getId();
            QueryWrapper<User> wrapper=new QueryWrapper<>();
            wrapper.eq("id",id);
            boolean b = userService.update(user, wrapper);
            return ResultData.ok().data("flag",b);
        }
    
     //不删除redis缓存
        @PostMapping("updateUser2")
        public ResultData updateUser2(@RequestBody User user){
            String id = user.getId();
            QueryWrapper<User> wrapper=new QueryWrapper<>();
            wrapper.eq("id",id);
            boolean b = userService.update(user, wrapper);
            return ResultData.ok().data("flag",b);
        }
    

    当我们更新数据库的数据时候,需要把redis的缓存清空。否则我们查询的数据是redis缓存中的数据,这样就会导致数据库和缓存数据不一致的问题。

    示例 调用没有加 @CacheEvict 注解的接口修改数据,在查询得到的数据是未修改之前的。

    image-20210603222933001

    image-20210603223045748

    所以在我们调用修改数据的接口的时候需要清除缓存

    加上 @CacheEvict 注解 清除对应的缓存此时在查询数据发现数据是最新的,跟数据库保持一致。

    image-20210603223520456

    过期时间

    我们已经实现了Spring Cache的基本功能,整合了Redis作为RedisCacheManger,但众所周知,我们在使用@Cacheable注解的时候是无法给缓存这是过期时间的。但有时候在一些场景中我们的确需要给缓存一个过期时间!这是默认的过期时间

    image-20210603223643251

    数据有效期时间

    image-20210603235329932

    自定义过期时间

    image-20210603235053742

    使用新的redis配置,再次查询缓存到数据看数据有效期

    image-20210603235438931

    努力学习java的Cherish
  • 相关阅读:
    python3(四)list tuple
    python3(三)enc
    python3(二)
    Scala学习
    spark本地开发环境搭建及打包配置
    最常见的 Git 问题和操作清单汇总
    Idea离线安装plugins插件 如Lombok
    springboot httpsession.getAtt....is null
    idea打包报错Cleaning up unclosed ZipFile for archive D:m2commons-beanutilscommons-beanutils1.9.2...
    springboot https证书配置
  • 原文地址:https://www.cnblogs.com/cherish-code/p/14847720.html
Copyright © 2020-2023  润新知