Redis緩存實(shí)例分步詳解
一、簡介
1、場(chǎng)景
由于數(shù)據(jù)字典的變化不是很頻繁,而且系統(tǒng)對(duì)數(shù)據(jù)字典的訪問較頻繁,所以我們有必要把數(shù)據(jù)字典的數(shù)據(jù)存入緩存,減少數(shù)據(jù)庫壓力和提高訪問速度。這里,我們使用Redis作為系統(tǒng)的分布式緩存中間件。
2、RedisTemplate
在Spring Boot項(xiàng)目中中,默認(rèn)集成Spring Data Redis,Spring Data Redis針對(duì)Redis提供了非常方便的操作模版RedisTemplate,并且可以進(jìn)行連接池自動(dòng)管理。
二、引入Redis
1、項(xiàng)目中集成Redis
service-base模塊中添加redis依賴,Spring Boot 2.0以上默認(rèn)通過commons-pool2連接池連接Redis
<!-- spring boot redis緩存引入 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 緩存連接池-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- redis 存儲(chǔ) json序列化 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>2、添加Redis連接配置
service-core的 application.yml 中添加如下配置
#spring:
redis:
host: 192.168.100.100
port: 6379
database: 0
password: 123456 #默認(rèn)為空
timeout: 3000ms #最大等待時(shí)間,超時(shí)則拋出異常,否則請(qǐng)求一直等待
lettuce:
pool:
max-active: 20 #最大連接數(shù),負(fù)值表示沒有限制,默認(rèn)8
max-wait: -1 #最大阻塞等待時(shí)間,負(fù)值表示沒限制,默認(rèn)-1
max-idle: 8 #最大空閑連接,默認(rèn)8
min-idle: 0 #最小空閑連接,默認(rèn)0
3、啟動(dòng)Redis服務(wù)
遠(yuǎn)程連接Linux服務(wù)器,這里本地使用centos虛擬機(jī)上的redis
#啟動(dòng)服務(wù)
cd /usr/local/redis-5.0.7
bin/redis-server redis.conf
三、測(cè)試RedisTemplate
1、存值測(cè)試
test中創(chuàng)建測(cè)試類RedisTemplateTests
@SpringBootTest
@RunWith(SpringRunner.class)
public class RedisTemplateTests {
@Resource
private RedisTemplate redisTemplate;
@Resource
private DictMapper dictMapper;
@Test
public void saveDict(){
Dict dict = dictMapper.selectById(1);
//向數(shù)據(jù)庫中存儲(chǔ)string類型的鍵值對(duì), 過期時(shí)間5分鐘
redisTemplate.opsForValue().set("dict", dict, 5, TimeUnit.MINUTES);
}
}發(fā)現(xiàn)RedisTemplate默認(rèn)使用了JDK的序列化方式存儲(chǔ)了key和value,可讀性差

2、Redis配置文件
service-base中添加RedisConfig,我們可以在這個(gè)配置文件中配置Redis序列化方案
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//首先解決key的序列化方式
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
//解決value的序列化方式
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
//序列化時(shí)將類的數(shù)據(jù)類型存入json,以便反序列化的時(shí)候轉(zhuǎn)換成正確的類型
ObjectMapper objectMapper = new ObjectMapper();
//objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
// 解決jackson2無法反序列化LocalDateTime的問題
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
return redisTemplate;
}
}再次測(cè)試,key使用了字符串存儲(chǔ),value使用了json存儲(chǔ)

3、取值測(cè)試
@Test
public void getDict(){
Dict dict = (Dict)redisTemplate.opsForValue().get("dict");
System.out.println(dict);
}四、將數(shù)據(jù)字典存入redis
DictServiceImpl
注意:當(dāng)redis服務(wù)器宕機(jī)時(shí),我們不要拋出異常,要正常的執(zhí)行后面的流程,使業(yè)務(wù)可以正常的運(yùn)行
@Resource
private RedisTemplate redisTemplate;
@Override
public List<Dict> listByParentId(Long parentId) {
//先查詢r(jià)edis中是否存在數(shù)據(jù)列表
List<Dict> dictList = null;
try {
dictList = (List<Dict>)redisTemplate.opsForValue().get("srb:core:dictList:" + parentId);
if(dictList != null){
log.info("從redis中取值");
return dictList;
}
} catch (Exception e) {
log.error("redis服務(wù)器異常:" + ExceptionUtils.getStackTrace(e));//此處不拋出異常,繼續(xù)執(zhí)行后面的代碼
}
log.info("從數(shù)據(jù)庫中取值");
dictList = baseMapper.selectList(new QueryWrapper<Dict>().eq("parent_id", parentId));
dictList.forEach(dict -> {
//如果有子節(jié)點(diǎn),則是非葉子節(jié)點(diǎn)
boolean hasChildren = this.hasChildren(dict.getId());
dict.setHasChildren(hasChildren);
});
//將數(shù)據(jù)存入redis
try {
redisTemplate.opsForValue().set("srb:core:dictList:" + parentId, dictList, 5, TimeUnit.MINUTES);
log.info("數(shù)據(jù)存入redis");
} catch (Exception e) {
log.error("redis服務(wù)器異常:" + ExceptionUtils.getStackTrace(e));//此處不拋出異常,繼續(xù)執(zhí)行后面的代碼
}
return dictList;
}集成redis總結(jié):
(1)導(dǎo)入相關(guān)依賴;
(2)配置redis連接信息;
(3)測(cè)試連接,取值測(cè)試,存值測(cè)試;
(4)根據(jù)自己的需要配置序列化器,否則默認(rèn)使用jdk的序列化器。
redis業(yè)務(wù)總結(jié):
(1)首先查詢r(jià)edis中有無對(duì)應(yīng)的緩存信息,有的話取出直接返回,沒有執(zhí)行(2),如果redis因?yàn)槟撤N原因連接不上比如宕機(jī),此時(shí)打印錯(cuò)誤日志,繼續(xù)查詢數(shù)據(jù)庫;
(2)沒有的話查詢數(shù)據(jù)庫,將數(shù)據(jù)存放進(jìn)redis并返回?cái)?shù)據(jù)。
到此這篇關(guān)于Redis緩存實(shí)例分步詳解的文章就介紹到這了,更多相關(guān)Redis緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)鼠標(biāo)隨機(jī)移動(dòng)效果的示例代碼
有的時(shí)候我們需要鼠標(biāo)一直滑動(dòng)的情況,為了節(jié)省時(shí)間,本文用Java語言寫了一個(gè)腳本,可以實(shí)現(xiàn)鼠標(biāo)隨機(jī)移動(dòng),感興趣的小伙伴可以了解一下2022-05-05
springboot中用fastjson處理返回值為null的屬性值
在本篇文章里小編給大家整理的是一篇關(guān)于springboot中用fastjson處理返回值問題詳解內(nèi)容,需要的朋友們參考下。2020-03-03
springboot啟動(dòng)不了也不報(bào)錯(cuò)的問題及解決
這篇文章主要介紹了springboot啟動(dòng)不了也不報(bào)錯(cuò)的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
Spring?Boot?多數(shù)據(jù)源處理事務(wù)的思路詳解
這篇文章主要介紹了Spring?Boot?多數(shù)據(jù)源如何處理事務(wù),本文單純就是技術(shù)探討,要從實(shí)際應(yīng)用中來說的話,我并不建議這樣去玩分布式事務(wù)、也不建議這樣去玩多數(shù)據(jù)源,畢竟分布式事務(wù)主要還是用在微服務(wù)場(chǎng)景下,對(duì)Spring?Boot?多數(shù)據(jù)源事務(wù)相關(guān)知識(shí)感興趣的朋友參考下本文2022-06-06
java?-jar/-cp啟動(dòng)添加外部的依賴包方式
這篇文章主要介紹了java?-jar/-cp啟動(dòng)添加外部的依賴包方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01

