springboot @Cacheable註解實現Redis快取
目錄:
回到頂部
0、前言
在專案中,快取作為一種高效的提升效能的手段,幾乎必不可少,Redis作為其中的佼佼者被廣泛應用;
回到頂部一、spring boot整合Redis
1、新增依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2、配置檔案增加Redis配置
####### Redis ################ #第幾個資料庫,由於redis中資料庫不止一個(預設會開啟15個) spring.redis.database=1 # 也可指定為127.0.0.1 spring.redis.host=localhost spring.redis.port=6379 spring.redis.password=88888888 # springboot2.x以上如此配置,由於2.x的客戶端是lettuce # 單位要帶上 spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.min-idle=0 spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.max-wait=10000ms spring.redis.lettuce.shutdown-timeout=100ms # springboot1.x如此配置,由於1.x的客戶端是jedis #spring.redis.jedis.pool.max-active=8 #spring.redis.jedis.pool.min-idle=0 #spring.redis.jedis.pool.max-idle=8 #spring.redis.jedis.pool.max-wait=-1 #spring.redis.timeout=500
3、使用
這樣就整合進來了,就可以使用了,有兩種template可以直接使用,RedisTemplate和StringRedisTemplate,有opsForValue、opsForList、opsForSet、opsForZset、opsForHash幾種訪問方法,簡單示例如下:
@Resource private RedisTemplate redisTemplate; // 寫入快取 redisTemplate.opsForValue().set("111","anson"); //讀取快取 String str = redisTemplate.opsForValue().get("111").toString();
執行後可以檢視到快取中已經寫入,讀取也正常讀取出來
4、總結:
可以看到,寫入Redis的是經過轉碼的,不方便檢視,一般我們在使用的時候,會替換掉它預設的解析器,並且將相關操作封裝成工具類方便使用;通常Redis我們是作為快取伺服器來使用,實際專案中,快取有兩種方式,一種是手動的方式:就是像上面的方式,將Redis的解析器替換,然後封裝工具類;在使用的地方,先判斷快取中時候有需要的資料,沒有的換就從資料庫中去取,然後寫入Redis快取,有的話就直接從Redis快取取;手動的方式雖然有時候更靈活,但是每個方法都需要寫一堆程式碼,很累贅,基本上我們是不會用這種方式的,所以上面的方式只是簡單介紹,什麼封裝工具類啊那些都沒貼程式碼出來,想用這種方式的自己去百度,一大堆;
快取的第二種方式就是配合註解實現快取,方便,只需要在需要快取的方法上加上註解即可,實際專案中,基本都是使用這種方式,下面介紹
回到頂部二、@Cacheable註解實現Redis快取
1、新增依賴
<!--4、整合redis --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.4.2</version> </dependency> <!-- redis依賴,2.0以上使用這個依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 快取依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
2、配置檔案中增加配置
####### Redis ################ #第幾個資料庫,由於redis中資料庫不止一個 spring.redis.database=1 # 也可指定為127.0.0.1 spring.redis.host=localhost spring.redis.port=6379 spring.redis.password=88888888 # springboot2.x以上如此配置,由於2.x的客戶端是lettuce # 單位要帶上 spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.min-idle=0 spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.max-wait=10000ms spring.redis.lettuce.shutdown-timeout=100ms # springboot1.x如此配置,由於1.x的客戶端是jedis #spring.redis.jedis.pool.max-active=8 #spring.redis.jedis.pool.min-idle=0 #spring.redis.jedis.pool.max-idle=8 #spring.redis.jedis.pool.max-wait=-1 #spring.redis.timeout=500
3、實現自定義快取管理器
package com.anson.config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.serializer.*; import java.time.Duration; /** * @description: redis快取配置類 * @author: anson * @Date: 2019/12/8 21:34 */ @Configuration @EnableCaching public class RedisCacheConfig extends CachingConfigurerSupport { private static final Logger logger = LoggerFactory.getLogger(RedisCacheConfig.class); // 自定義key生成器 @Bean public KeyGenerator keyGenerator(){ return (o, method, params) ->{ StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); // 類目 sb.append(method.getName()); // 方法名 for(Object param: params){ sb.append(param.toString()); // 引數名 } return sb.toString(); }; } // 配置快取管理器 @Bean public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) { RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(60000000)) // 60s快取失效 // 設定key的序列化方式 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer())) // 設定value的序列化方式 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer())) // 不快取null值 .disableCachingNullValues(); RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory) .cacheDefaults(config) .transactionAware() .build(); logger.info("自定義RedisCacheManager載入完成"); return redisCacheManager; } // key鍵序列化方式 private RedisSerializer<String> keySerializer() { return new StringRedisSerializer(); } // value值序列化方式 private GenericJackson2JsonRedisSerializer valueSerializer(){ return new GenericJackson2JsonRedisSerializer(); // return new GenericFastJsonRedisSerializer(); } }
4、使用:可以直接使用了,在UserServiceImpl中
@Override @Cacheable(cacheNames = "user" ,key="#id") public User selectByPrimaryKey(Integer id) { return usermapper.selectByPrimaryKey(id); } @Override @Cacheable(cacheNames = "users") public List<User> getAll() { return usermapper.getAll(); }
其中,key如果不設定,會根據我們設定的生成器生成KEY,如果自己設定的話,有幾種方式,下面介紹一下:
A、基本形式
@Cacheable(value="cacheName", key"#id")
public User method(int id);
B、組合形式
@Cacheable(value="cacheName", key"T(String).valueOf(#name).concat('-').concat(#password))
public Usermethod(int name, String password);
C、物件形式
@Cacheable(value="cacheName", key"#user.id)
public Usermethod(User user);
D、自定義Key生成器
@Cacheable(value="gomeo2oCache", keyGenerator = "keyGenerator")
public Usermethod(User user);
5、測試
我們 開啟druid的SQL監控,然後在swagger中進行操作,在Redis desktop manager中檢視Redis,就可以看到第一次查詢執行了資料庫查詢,並把結果存進了Redis中,以後執行同樣的查詢,在快取沒過期之前,都直接從Redis獲取,不再執行資料庫查詢,可見Redis快取成功執行和釋放了資料庫的壓力了;
附:Redis Windows下簡單實用以及Redis GUI工具Redis desktop manager的使用,也簡單介紹下:
1、Redis Windows版的簡單使用:
下載Redis Windows版,解壓後看到
先點選開啟Redis-server.exe,再開啟Redis-cli.exe,Redis已經以預設的方式啟動起來了,其中Redis-server.exe就是Redis服務,Redis-cli.exe是客戶端工具,用來以命令操作Redis的;
這時候就可以使用Redis,預設密碼是空的,埠是6379;我們設定一下密碼:
config set requirepass “你的密碼” //設定密碼
auth “你的密碼” //驗證密碼是否成功設定
flushall ,是清除所有快取的命令,用來清除重新測試的,
其他命令就不多介紹了,需要用到自行百度
2、Redis desktop manager的使用
下載安裝包,安裝,然後填入密碼連線即可
回到頂部三、後續
第二種方式中註解實現Redis快取的方式有個缺點,就是失效時間都統一配置了,更多時候,我們希望失效時間可以每個方法單獨配置,所以二的方法還需要改造,實現失效時間單獨配置的功能;還有Redis一般我們都會搭建叢集實現高可用,關於Linux、docker搭建Redis叢集的方式,這些專案實戰乾貨我們以後再來詳細聊;