springboot集成Redis实现缓存功能

1.加入Redis依赖

<!--springboot缓存-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
            </dependency>
        <!-- redis依赖,不引入则默认使用ConcurrenMapCacheManager -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- 操作redis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>

2.在Application入口添加@EnableCaching注解开启缓存功能

//扫描该包目录下的文件
@SpringBootApplication
//扫描mapper文件
@MapperScan(basePackages = "com.xxx.xxx.dao")
//开启缓存
@EnableCaching
public class SpringbootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }
    }

3.在application.yml文件中添加配置信息

#    redis相关配置
spring:
  redis:
    #地址
    host: localhost
    #端口
    port: 6379
    #索引库
    database: 0
    #密码,默认为空,不用填
    password: 
    #超时时间(毫秒)
    timeout: 5000
    jedis:
      pool:
        #连接池最大连接数(使用负值表示没有限制)
        max-active: 8
        #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1
        #连接池中的最大空闲连接
        max-idle: 8
        #连接池中的最小空闲连接
        min-idle: 1
  cache:
    #设置缓存类型
    type: redis
    redis:
      #缓存存活时间,不设置则没有过期时间
      time-to-live: 1800000

4.配置Redis缓存配置文件


/**
 * Redis缓存配置
 *
 * @author sxyuser
 */
@Configuration
public class RedisCacheConfig extends CachingConfigurerSupport {
    /**
     * 配置Redistemplate
     *
     * @param factory
     * @return
     */
    @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.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
        om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"));
        jackson2JsonRedisSerializer.setObjectMapper(om);

        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        template.setHashKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }

    /**
     * 使用CacheManager缓存
     *
     * @param factory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {

        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);

        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
        om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"));
        jackson2JsonRedisSerializer.setObjectMapper(om);

        // 配置序列化(解决乱码的问题),过期时间30秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(18000))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
    }

    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return (target, method, objects) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getName());
            sb.append("::").append(method.getName()).append(":");
            for (Object obj : objects) {
                sb.append(obj.toString());
            }
            return sb.toString();
        };
    }
}

5.缓存注解的使用,一般放在impl实现类的方法上面
Spring为我们提供了几个注解来支持Spring Cache。其核心主要是@Cacheable和@CacheEvict。使用@Cacheable标记的方法在执行后Spring Cache将缓存其返回结果,而使用@CacheEvict标记的方法会在方法执行前或者执行后移除Spring Cache中的某些元素。还有其他一些注解,比如:@CacheConfig,@CachePut,@Caching等

@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

@Cacheable 作用和配置方法

参数 解释 例子
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 @Cacheable(value=”cache1”)@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 @Cacheable(value=”test”,key=”#username”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 @Cacheable(value=”test”,condition=”#username.length()>2”)

@CachePut作用和配置方法

使用CachePut注解,该方法每次都会执行,会清除对应的key值得缓存(或者更新),分为以下两种情况:

如果返回值null,下次进行该key值查询时,还会查一次数据库,此时相当于@CacheEvict注解;
如果返回值不为null,此时会进行该key值缓存的更新,更新缓存值为返回的数据;

参数 解释 例子
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 @Cacheable(value=”cache1”)@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 @Cacheable(value=”test”,key=”#username”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 @Cacheable(value=”test”,condition=”#username.length()>2”)

例子:

 @CachePut(value="image",key = "#imageManage.id")
    @Override
    public ImageManage update(ImageManage imageManage) {
        this.imageManageDao.update(imageManage);
        return this.queryById(imageManage.getId());
    }

@CacheEvict作用和配置方法

@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空

参数 解释 例子
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 @Cacheable(value=”cache1”)@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 @Cacheable(value=”test”,key=”#username”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 @Cacheable(value=”test”,condition=”#username.length()>2”)
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 @CachEvict(value=”cache”,allEntries=true)
beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 @CachEvict(value=”cache”,beforeInvocation=true)

实例

 @CacheEvict(key = "'queryAll'")
    public ImageManage insert(ImageManage imageManage) {
        this.imageManageDao.insert(imageManage);
        return imageManage;
    }

@Caching用于定制复杂的缓存规则

例如:

@Caching(
            cacheable = {
                    @Cacheable(value = "emp",key = "#lastName")
            },
            put = {
                    @CachePut(value = "emp",key = "#result.id"),
                    @CachePut(value = "emp",key = "#result.email"),
            }
    )

@CacheConfig(cacheNames=“emp”)用于标注在类上,可以存放该类中所有缓存的公有属性,比如设置缓存的名字。

参考博客
https://blog.csdn.net/u012240455/article/details/80844361?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1

猜你喜欢

转载自blog.csdn.net/weixin_43897590/article/details/105897103