Redis 在Springboot中的使用体现

安装Redis步骤此处不做介绍,代码的执行需要开启Redis。

 

一、相关代码与配置

目录结构

Redis 在Springboot中的使用体现

1、application.properties

#==== redies ====

# Redis数据库索引(默认为0)

spring.redis.database=0

# Redis服务器地址

spring.redis.host=127.0.0.1

# Redis服务器连接端口

spring.redis.port=6379

# Redis服务器连接密码(默认为空)

spring.redis.password=

# 连接池最大连接数(使用负值表示没有限制)

spring.redis.pool.max-active=8

# 连接池最大阻塞等待时间(使用负值表示没有限制)

spring.redis.pool.max-wait=-1

# 连接池中的最大空闲连接

spring.redis.pool.max-idle=8

# 连接池中的最小空闲连接

spring.redis.pool.min-idle=0

# 连接超时时间(毫秒)

spring.redis.timeout=0

2、RedisConfig类

package com.demo.myone.config;



import org.springframework.beans.factory.annotation.Value;

import org.springframework.cache.CacheManager;

import org.springframework.cache.annotation.CachingConfigurerSupport;

import org.springframework.cache.annotation.EnableCaching;

import org.springframework.cache.interceptor.KeyGenerator;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

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.core.StringRedisTemplate;

import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;



import com.fasterxml.jackson.annotation.JsonAutoDetect;

import com.fasterxml.jackson.annotation.PropertyAccessor;

import com.fasterxml.jackson.databind.ObjectMapper;



/**

* Description:Redis缓存配置类

* User: adg

* Date: 2018/10/18

*/

@Configuration

@EnableCaching //开启缓存

public class RedisConfig extends CachingConfigurerSupport{



@Value("${spring.redis.host}")

private String host;

@Value("${spring.redis.port}")

private int port;

@Value("${spring.redis.timeout}")

private int timeout;



//自定义缓存key生成策略

@Bean

public KeyGenerator wiselyKeyGenerator() {

return (target, method, params) -> {

StringBuilder sb = new StringBuilder();

sb.append(target.getClass().getName());

sb.append(method.getName());

for (Object obj : params) {

sb.append(obj.toString());

}

return sb.toString();

};

}



//缓存管理器

@Bean

public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {

RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);

//设置缓存过期时间

cacheManager.setDefaultExpiration(10000);

return cacheManager;

}

@Bean

public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory){

StringRedisTemplate template = new StringRedisTemplate(factory);

setSerializer(template);//设置序列化工具

template.afterPropertiesSet();

return template;

}

private void setSerializer(StringRedisTemplate template){

@SuppressWarnings({ "rawtypes", "unchecked" })

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.setValueSerializer(jackson2JsonRedisSerializer);

}

}

 

二、相关注解

  • @EnableCache开启缓存功能,项目只需要在某个类上加一次该注解即可。
  • @CacheConfig有时候一个类中可能会有多个缓存操作,而这些缓存操作可能是重复的。这个时候可以使用@CacheConfig,它是一个类级别的注解,允许共享缓存的名称、KeyGenerator、CacheManager 和CacheResolver。(这样配置了,就不用在各个操作中单独配name=“xxx”)
  • @Cacheable将查询结果缓存到redis中,(key="#p0")指定传入的第一个参数作为redis的key。
  • @CachePut,指定key,将更新的结果同步到redis中
  • @CacheEvict,指定key,删除缓存数据,allEntries=true,方法调用后将立即清除缓存

 

三、遇到的问题

报错:

Null key returned for cache operation (maybe you are using named params on classes without debug info?)

原因:

缓存机制是作用到Service层的,而dao或者repository层缓存用注解用key的话它会认定为null。这样我们就用KeyGenerator来提前生成key的生成策略。

解决:

把以下代码加入添加了 (@EnableCaching //开启缓存功能)注解的类中

//自定义缓存key生成策略

@Bean

public KeyGenerator wiselyKeyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
};
}

这样就能使用了

@Cacheable(keyGenerator = "wiselyKeyGenerator")

User findById(@Param("id") int id)

 

四、使用效果

在配置文件中加入

logging.level.com.demo.myone.dao=debug

即可在控制台打印出sql。

1、先添加一条数据(这时缓存中还没有该数据)

2、第一次查询该条数据

Redis 在Springboot中的使用体现

此时是从数据库查出的数据

3、当再次执行时

Redis 在Springboot中的使用体现

可以看到,第二次没有打印sql,此时是从缓存中查出了数据。