SpringBoot整合Redis使用注解進(jìn)行緩存方式
Hello,各位小伙伴,最近項(xiàng)目中需要將一些常用的數(shù)據(jù)緩存起來(lái),毫無(wú)疑問(wèn),我們采用了Redis來(lái)緩存數(shù)據(jù)。那么使用Redis緩存數(shù)據(jù)有哪些方式呢?接下來(lái)我會(huì)一一道來(lái)。
1.環(huán)境搭建
引入Redis依賴(lài)以及Spring相關(guān)的依賴(lài)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>2.使用RedisTemplate
使用RedisTemplate調(diào)用API時(shí),我們通常需要去配置key,value的序列化器,以及創(chuàng)建一個(gè)RedisUtils類(lèi)來(lái)完成緩存的增刪改查以及過(guò)期時(shí)間的設(shè)置。
配置如下:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 設(shè)置key的序列化方式
template.setKeySerializer(RedisSerializer.string());
// 設(shè)置value的序列化方式
template.setValueSerializer(RedisSerializer.json());
// 設(shè)置hash的key的序列化方式
template.setHashKeySerializer(RedisSerializer.string());
// 設(shè)置hash的value的序列化方式
template.setHashValueSerializer(RedisSerializer.json());
template.afterPropertiesSet();
return template;
}
}RedisUtils:
public class RedisUtils {
@Resource
private RedisTemplate<String, Object> redisTemplate;
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通緩存放入
*
* @param key 鍵
* @param value 值
*/
public void set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 普通緩存放入并設(shè)置時(shí)間
*
* @param key 鍵
* @param value 值
* @param time 時(shí)間(秒) time要大于0 如果time小于等于0 將設(shè)置無(wú)限期
*/
public void set(String key, Object value, long time) {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
}
/**
* 向一張hash表中放入數(shù)據(jù),如果不存在將創(chuàng)建
*
* @param key 鍵
* @param item 項(xiàng)
* @param value 值
*/
public void hset(String key, String item, Object value) {
redisTemplate.opsForHash().put(key, item, value);
}
/**
* 向一張hash表中放入數(shù)據(jù),如果不存在將創(chuàng)建
*
* @param key 鍵
* @param item 項(xiàng)
* @param value 值
* @param time 時(shí)間(秒) 注意:如果已存在的hash表有時(shí)間,這里將會(huì)替換原有的時(shí)間
*/
public void hset(String key, String item, Object value, long time, TimeUnit timeUnit) {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time, timeUnit);
}
}
/**
* @param key 鍵
* @param map 多個(gè)field-value
*/
public void hmset(String key, Map<String, Object> map) {
redisTemplate.opsForHash().putAll(key, map);
}
/**
* @param key 鍵
* @param map 多個(gè)field-value
* @param time 過(guò)期時(shí)間
* @param timeUnit 時(shí)間單位
*/
public void hmset(String key, Map<String, Object> map, long time, TimeUnit timeUnit) {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time, timeUnit);
}
}
/**
* @param key 鍵
* @param item Field
* @return 獲得的值
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* @param key 鍵
* @return hash表中key對(duì)應(yīng)的map
*/
public Map<Object, Object> hEntries(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* @param key 鍵
* @param value 值
*/
public void sadd(String key, Object value) {
redisTemplate.opsForSet().add(key, value);
}
/**
* @param key 鍵
* @param value 值
* @param time 過(guò)期時(shí)間
* @param timeUnit 時(shí)間單位
*/
public void sadd(String key, Object value, long time, TimeUnit timeUnit) {
redisTemplate.opsForSet().add(key, value);
if (time > 0) {
expire(key, time, timeUnit);
}
}
/**
* @param key 鍵
* @return 數(shù)據(jù)
*/
public Set<Object> smembers(String key) {
return redisTemplate.opsForSet().members(key);
}
public void expire(String key, long time, TimeUnit timeUnit) {
if (time > 0) {
redisTemplate.expire(key, time, timeUnit);
}
}
/**
* 根據(jù)key 獲取過(guò)期時(shí)間
*
* @param key 鍵 不能為null
* @return 時(shí)間(秒) 返回0代表為永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
}通過(guò)以上的配置,我們?cè)谑褂镁彺娴臅r(shí)候,直接調(diào)用API就可以進(jìn)行操作了。但是有個(gè)問(wèn)題就是,我們?cè)诰彺嬉恍┏S脭?shù)據(jù)的時(shí)候,通常我們需要先判斷一下緩存中有沒(méi)有該key,如果沒(méi)有我們?cè)偃?shù)據(jù)庫(kù)中查詢(xún)出來(lái),并緩存。
這樣的話(huà)我們需要去做一些判斷的操作,緩存中有就去緩存中取,沒(méi)有就從數(shù)據(jù)庫(kù)中取出來(lái)并緩存。那么有沒(méi)有更方便的操作方式呢,答案當(dāng)然是有的。
3.使用@EnableCaching+@Cacheable
Spring為我們提供了Caching模塊,我們可以該模塊給我們提供的功能,使用注解很方便完成數(shù)據(jù)緩存
在使用的過(guò)程中,我發(fā)現(xiàn),雖然我們配置了RedisTemplate的序列化,但是對(duì)于基于注解的Redis緩存來(lái)說(shuō)是無(wú)效的,我們需要配置自定義的RedisCacheManager
配置如下:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 設(shè)置key的序列化方式
template.setKeySerializer(RedisSerializer.string());
// 設(shè)置value的序列化方式
template.setValueSerializer(RedisSerializer.json());
// 設(shè)置hash的key的序列化方式
template.setHashKeySerializer(RedisSerializer.string());
// 設(shè)置hash的value的序列化方式
template.setHashValueSerializer(RedisSerializer.json());
template.afterPropertiesSet();
return template;
}
@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory factory) {
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(factory);
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
}
}使用方法:
- 在啟動(dòng)類(lèi)上加上
@EnableCaching - 在需要緩存數(shù)據(jù)的方法上加上
@Cacheable(cacheNames = "xxx"),方法的返回值就是我們需要緩存的數(shù)據(jù) - 基于以上的操作,我們就可以很方便的將需要緩存的數(shù)據(jù)緩存到Redis
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot啟動(dòng)時(shí)沒(méi)有日志的原因分析
這篇文章主要介紹了springboot啟動(dòng)時(shí)沒(méi)有日志的原因分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
java通過(guò)客戶(hù)端訪問(wèn)服務(wù)器webservice的方法
這篇文章主要介紹了java通過(guò)客戶(hù)端訪問(wèn)服務(wù)器webservice的方法,涉及java創(chuàng)建與調(diào)用webservice的相關(guān)技巧,需要的朋友可以參考下2016-08-08
SpringBoot之QueryDsl嵌套子查詢(xún)問(wèn)題
這篇文章主要介紹了SpringBoot之QueryDsl嵌套子查詢(xún)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
如何使用Spring AOP的通知類(lèi)型及創(chuàng)建通知
這篇文章主要給大家介紹了關(guān)于如何使用Spring AOP的通知類(lèi)型及創(chuàng)建通知的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring AOP具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12

