1.Redis的介绍
       Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。
中文文档:https://www.redis.net.cn/
2.入门
2.1 引入依赖
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>
 
 
 <dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-pool2</artifactId>
 <version>2.6.0</version>
 </dependency>
 
 | 
2.2 添加配置类
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 
 | package com.atguigu.yygh.common.config;
 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.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.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.lang.reflect.Method;
 import java.time.Duration;
 
 
 
 
 
 
 
 @Configuration
 @EnableCaching
 public class RedisConfig {
 
 
 
 
 @Bean
 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());
 sb.append(method.getName());
 for (Object obj : params) {
 sb.append(obj.toString());
 }
 return sb.toString();
 }
 };
 }
 
 
 
 
 
 @Bean
 public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
 RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
 redisTemplate.setConnectionFactory(redisConnectionFactory);
 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);
 
 
 redisTemplate.setKeySerializer(new StringRedisSerializer());
 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
 redisTemplate.setHashKeySerializer(new StringRedisSerializer());
 redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
 
 redisTemplate.afterPropertiesSet();
 return redisTemplate;
 }
 
 
 
 
 
 
 @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);
 
 
 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)
 .build();
 return cacheManager;
 }
 
 }
 
 | 
说明:
          @EnableCaching:标记注解 @EnableCaching,开启缓存,并配置Redis缓存管理器。@EnableCaching 注释触发后置处理器, 检查每一个Spring bean 的 public 方法是否存在缓存注解。如果找到这样的一个注释, 自动创建一个代理拦截方法调用和处理相应的缓存行为。
2.3 配置文件中加入redis的配置
application.properties
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | spring.redis.host=localhostspring.redis.port=6379
 spring.redis.database= 0
 spring.redis.timeout=1800000
 
 spring.redis.lettuce.pool.max-active=20
 spring.redis.lettuce.pool.max-wait=-1
 
 spring.redis.lettuce.pool.max-idle=5
 spring.redis.lettuce.pool.min-idle=0
 
 | 
2.4 使用Spring Cache + Redis执行缓存操作
2.1.2 @Cacheable
          根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。
| 属性/方法名 | 解释 | 
| value | 缓存名,必填,它指定了你的缓存存放在哪块命名空间 | 
| cacheNames | 与 value 差不多,二选一即可 | 
| key | 可选属性,可以使用 SpEL 标签自定义缓存的key | 
2.1.2 @CachePut
          使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。
| 属性/方法名 | 解释 | 
| value | 缓存名,必填,它指定了你的缓存存放在哪块命名空间 | 
| cacheNames | 与 value 差不多,二选一即可 | 
| key | 可选属性,可以使用 SpEL 标签自定义缓存的key | 
2.1.3 @CacheEvict
          使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上
| 属性/方法名 | 解释 | 
| value | 缓存名,必填,它指定了你的缓存存放在哪块命名空间 | 
| cacheNames | 与 value 差不多,二选一即可 | 
| key | 可选属性,可以使用 SpEL 标签自定义缓存的key | 
| allEntries | 是否清空所有缓存,默认为  false。如果指定为 true,则方法调用后将立即清空所有的缓存 | 
| beforeInvocation | 是否在方法执行前就清空,默认为  false。如果指定为 true,则在方法执行前就会清空缓存 | 
3.示例
下面的第一个方法是查询数据位list集合
	 @Cacheable(value = “dict”,keyGenerator = “keyGenerator”)   对方法的结果进行缓存
			value属性表示key的前缀  
			keyGenerator表示key的生成规则,生成规则在配置文件中配置,这里我们使用的是方法的全类名作为key的后缀
第二个方法是添加数据 添加数据会造成数据库中数据的变化 我们要清除缓存
     @CacheEvict(value = “dict”,allEntries = true)  清空指定的缓存
             value属性表示清空以dict为前缀的所有缓存
              allEntries 属性表示是否清空所有缓存,默认为  false。如果指定为 true,则方法调用后将立即清空所有的缓存  
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | @Override@Cacheable(value = "dict",keyGenerator = "keyGenerator")
 public List<Dict> findByParentId(Long parentId) {
 LambdaQueryWrapper<Dict> queryWrapper = new LambdaQueryWrapper<>();
 queryWrapper.eq(Dict::getParentId, parentId);
 List<Dict> dictList = dictMapper.selectList(queryWrapper);
 for (Dict dict : dictList) {
 dict.setHasChildren(this.isHasChildren(dict.getId()));
 }
 return dictList;
 }
 
 @CacheEvict(value = "dict",allEntries = true)
 public void importDictData(MultipartFile file) {
 try {
 EasyExcel.read(file.getInputStream(),DictEeVo.class,new DictListener(dictMapper)).sheet().doRead();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 
 
 
 
 | 
key的生成规则如下图:
