環境:SpringBoot2.1.1.RELEASE版本
一、SpringBoot配置Reids
1、pom引入spring-boot-starter-data-redis包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2、application.yml配置Redis地址、端口及基本信息
注:如果Redis開啟了密碼,在timeout前增加password:mima
# Spring配置 spring: # redis配置 redis: # 地址 host: 127.0.0.1 # 端口,默認為6379 port: 6379 # 連接超時時間 timeout: 10s lettuce: pool: # 連接池中的最小空閑連接 min-idle: 0 # 連接池中的最大空閑連接 max-idle: 8 # 連接池的最大數據庫連接數 max-active: 8 # #連接池最大阻塞等待時間(使用負值表示沒有限制) max-wait: -1m
二、增加RedisConfig.java啟動加載類
import java.time.Duration; 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.cache.RedisCacheManager.RedisCacheManagerBuilder; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.ListOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.SetOperations; import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; /*** * redis 配置 * @author*/ @Configuration @EnableCaching public class RedisCongif extends CachingConfigurerSupport { /** * 分割符 */ public static final String DECOLLATOR = ":"; /** * 應用前綴 */ public static final String APP_PREFIX = "redis"; /** * 緩存名前綴 */ public static final String CACHE_NAMES_PREFIX = APP_PREFIX + DECOLLATOR + "cacheNames" + DECOLLATOR; /** * 永不過期的緩存名 */ public static final String CACHE_NAME_FOREVER = CACHE_NAMES_PREFIX + "forever"; /** * 10分鍾有效期的緩存名 */ public static final String CACHE_NAME_MINUTES_10 = CACHE_NAMES_PREFIX + "minutes-10"; /** * 30分鍾有效期的緩存名 */ public static final String CACHE_NAME_MINUTES_30 = CACHE_NAMES_PREFIX + "minutes-30"; /** * 1個小時有效期的緩存名 */ public static final String CACHE_NAME_HOURS_01 = CACHE_NAMES_PREFIX + "hours-1"; /** * 24小時有效期的緩存名 */ public static final String CACHE_NAME_HOURS_24 = CACHE_NAMES_PREFIX + "hours-24"; /** * 12小時有效期的緩存名 */ public static final String CACHE_NAME_HOURS_12 = CACHE_NAMES_PREFIX + "hours-12"; /** * 30天有效期的緩存名 */ public static final String CACHE_NAME_DAYS_30 = CACHE_NAMES_PREFIX + "days-30"; /** * 選擇redis作為默認緩存工具
* SpringBoot2.0以上CacheManager配置方式 * @param redisTemplate * @return * */ @Bean public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) { RedisCacheConfiguration defaultCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() // 設置key為String .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getStringSerializer())) // 設置value 為自動轉Json的Object .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer())) // 不緩存null .disableCachingNullValues() // 緩存數據保存1小時 .entryTtl(Duration.ofHours(1)); RedisCacheManager redisCacheManager = RedisCacheManagerBuilder // Redis 連接工廠 .fromConnectionFactory(redisTemplate.getConnectionFactory()) // 緩存配置 .cacheDefaults(defaultCacheConfiguration) // 配置同步修改或刪除 put/evict .transactionAware() .build(); // RedisCacheManager rcm = new RedisCacheManager(redisTemplate); return redisCacheManager; } /** * retemplate相關配置 * @param factory * @return */ @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); // 配置連接工廠 template.setConnectionFactory(factory); //使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(默認使用JDK的序列化方式) Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); // 指定要序列化的域,field,get和set,以及修飾符范圍,ANY是都有包括private和public om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 指定序列化輸入的類型,類必須是非final修飾的,final修飾的類,比如String,Integer等會跑出異常 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jacksonSeial.setObjectMapper(om); // 值采用json序列化 template.setValueSerializer(jacksonSeial); //使用StringRedisSerializer來序列化和反序列化redis的key值 template.setKeySerializer(new StringRedisSerializer()); // 設置hash key 和value序列化模式 template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(jacksonSeial); template.afterPropertiesSet(); return template; } /** * 對hash類型的數據操作 * * @param redisTemplate * @return */ @Bean public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForHash(); } /** * 對redis字符串類型數據操作 * * @param redisTemplate * @return */ @Bean public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForValue(); } /** * 對鏈表類型的數據操作 * * @param redisTemplate * @return */ @Bean public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForList(); } /** * 對無序集合類型的數據操作 * * @param redisTemplate * @return */ @Bean public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForSet(); } /** * 對有序集合類型的數據操作 * * @param redisTemplate * @return */ @Bean public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForZSet(); } }
需要注意的是,SpringBoot2.0以上版本(不太確定)RedisTempate<K, V> 必須要定義K和V,在SpringBoot1.5x版本以下是不需要的,CacheManager配置如下:
@Bean public CacheManager cacheManager(RedisTemplate redisTemplate) { RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate); // 設置默認緩存過期時間(0為不失效) // redisCacheManager.setDefaultExpiration(0);//秒 // 設置緩存的value屬性的過期時間(單位秒) Map<String, Long> expiresMap = new HashMap<String, Long>(); expiresMap.put(CACHE_NAME_FOREVER, 0L);// 0表示永不失效 expiresMap.put(CACHE_NAME_MINUTES_10, 60L * 10); expiresMap.put(CACHE_NAME_MINUTES_30, 60L * 30); expiresMap.put(CACHE_NAME_HOURS_01, 60L * 60); expiresMap.put(CACHE_NAME_HOURS_24, 60L * 60 * 24); expiresMap.put(CACHE_NAME_HOURS_12, 60L * 60 * 12); expiresMap.put(CACHE_NAME_DAYS_30, 60L * 60 * 24 * 30); redisCacheManager.setExpires(expiresMap); return redisCacheManager; }
三、如何使用Redis,三種注解方式@Cacheable、@CachePut、@CacheEvict
/** * redis在serviceImpl里使用方式 * 1、Cacheable 的用法 * 緩存有數據時,從緩存獲取;沒有數據時,執行方法,並將返回值保存到緩存中 * @Cacheable 一般在查詢中使用 * 1) cacheNames 指定緩存區,沒有配置使用@CacheConfig指定的緩存區 * 2) key 指定緩存區的key * 3) 注解的值使用SpEL表達式(eq == lt < le <= gt > ge >=) * 1.1、時效性緩存(緩存24小時) * @Cacheable(value = RedisCongif.CACHE_NAME_HOURS_24) * 1.2、緩存到指定key * @Cacheable(key="'list'") * 1.3、condition 滿足條件緩存數據 * @Cacheable(key = "#id", condition = "#number ge 20") // >= 20 * 1.4、unless 滿足條件時否決緩存數據 * @Cacheable(key = "#id", unless = "#number lt 20") // < 20 * 2、CachePut 的用法 * 一定會執行方法,並將返回值保存到緩存中 * @CachePut 一般在新增和修改中使用 * 2.1、緩存到指定key * @CachePut(key = "#user.id") * 2.2、condition 滿足條件緩存數據 * @CachePut(key = "#user.id", condition = "#user.age ge 20") * 3、CacheEvict 的用法 * CacheEvict 來刪除緩存,@CacheEvict 就是一個觸發器,在每次調用被它注解的方法時,就會觸發刪除它指定的緩存的動作 * 3.1、根據key刪除緩存區中的數據 * @CacheEvict(key = "#id") * 3.2、根據條件配置 * allEntries = true :刪除整個緩存區的所有值,此時指定的key無效 * beforeInvocation = true :默認false,表示調用方法之后刪除緩存數據;true時,在調用之前刪除緩存數據(如方法出現異常) * @CacheEvict(key = "#id", allEntries = true) */
以上是個人配置Redis步驟,使用的是時效緩存方式:@Cacheable(value = RedisCongif.CACHE_NAME_HOURS_24),緩存24小時,24小時之后過期,會重新查詢數據庫獲取最新的數據再次緩存24小時。時效可以根據自己的需求進行配置10分鍾、30分鍾、1小時、12小時、1天、30天等等。
