Redis緩存實(shí)例分步詳解
一、簡介
1、場景
由于數(shù)據(jù)字典的變化不是很頻繁,而且系統(tǒng)對數(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針對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í)則拋出異常,否則請求一直等待
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
三、測試RedisTemplate
1、存值測試
test中創(chuàng)建測試類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類型的鍵值對, 過期時(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; } }
再次測試,key使用了字符串存儲(chǔ),value使用了json存儲(chǔ)
3、取值測試
@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)測試連接,取值測試,存值測試;
(4)根據(jù)自己的需要配置序列化器,否則默認(rèn)使用jdk的序列化器。
redis業(yè)務(wù)總結(jié):
(1)首先查詢r(jià)edis中有無對應(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Servlet入門級設(shè)置(超詳細(xì) IDEA2020版)
這篇文章主要介紹了詳解Servlet入門級設(shè)置(超詳細(xì) IDEA2020版),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Mybatis 如何批量刪除數(shù)據(jù)的實(shí)現(xiàn)示例
這篇文章主要介紹了Mybatis 如何批量刪除數(shù)據(jù)的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03SpringBoot項(xiàng)目使用mybatis-plus代碼生成的實(shí)例詳解
mybatis-plus是mybatis的增強(qiáng),不對mybatis做任何改變,涵蓋了代碼生成,自定義ID生成器,快速實(shí)現(xiàn)CRUD,自動(dòng)分頁,邏輯刪除等功能。本文就來講講SpringBoot項(xiàng)目如何使用mybatis-plus實(shí)現(xiàn)代碼生成,需要的可以了解一下2022-10-10利用Java多線程技術(shù)導(dǎo)入數(shù)據(jù)到Elasticsearch的方法步驟
這篇文章主要介紹了利用Java多線程技術(shù)導(dǎo)入數(shù)據(jù)到Elasticsearch的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07SPRING BOOT啟動(dòng)命令參數(shù)及源碼詳析
這篇文章主要給大家介紹了關(guān)于SPRING BOOT啟動(dòng)命令參數(shù)及源碼分析的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用SPRING BOOT具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12java swing實(shí)現(xiàn)貪吃蛇雙人游戲
這篇文章主要為大家詳細(xì)介紹了java swing實(shí)現(xiàn)貪吃蛇雙人小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01Mybatis自定義TypeHandler解決特殊類型轉(zhuǎn)換問題詳解
這篇文章主要介紹了Mybatis自定義TypeHandler解決特殊類型轉(zhuǎn)換問題詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11Java實(shí)現(xiàn)數(shù)字轉(zhuǎn)成英文的方法
這篇文章主要介紹了Java實(shí)現(xiàn)數(shù)字轉(zhuǎn)成英文的方法,涉及java數(shù)組與字符串的相關(guān)操作技巧,需要的朋友可以參考下2015-05-05tomcat報(bào)錯(cuò):Wrapper cannot find servlet class ...問題解決
這篇文章主要介紹了tomcat報(bào)錯(cuò):Wrapper cannot find servlet class ...問題解決的相關(guān)資料,需要的朋友可以參考下2016-11-11Java線程安全的常用類_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
在集合框架中,有些類是線程安全的,這些都是jdk1.1中的出現(xiàn)的。在jdk1.2之后,就出現(xiàn)許許多多非線程安全的類。 下面是這些線程安全的同步的類2017-06-06