使用StringRedisTemplate操作Redis方法詳解
Redis簡介
Redis 是一個(gè)開源(BSD許可)的,內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)系統(tǒng),它可以用作數(shù)據(jù)庫、緩存和消息中間件。支持事務(wù)5.0版本新增stream數(shù)據(jù)類型。
Spring boot單數(shù)據(jù)源配置
Springboot的redis單數(shù)據(jù)源配置特別簡單
(1)配置appliation.properties文件
spring.redis.host=x.x.x.x spring.redis.port=6379 #redis的數(shù)據(jù)庫號 spring.redis.database=4 spring.redis.timeout = 30000ms spring.redis.jedis.pool.max-active=200 spring.redis.jedis.pool.max-idle=0 spring.redis.lettuce.pool.max-idle=5 spring.redis.jedis.pool.max-wait=20000ms
(2)StringRedisTemplate的基本操作
StringRedisTemplate自動(dòng)關(guān)閉redis連接 //注入對象 @Autowired private StringRedisTemplate stringRedisTemplate; #獲取ValueOperations操作String數(shù)據(jù) ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue(); valueOperations.set("strRedis","StringRedisTemplate"); valueOperations.get("strRedis"); #設(shè)置過期時(shí)間 set("timeStep", new Date().getTime()+"", 2 ,TimeUnit.MINUTES); #獲取SetOperations操作Set數(shù)據(jù) SetOperations<String, String> set = stringRedisTemplate.opsForSet(); set.add("set1","22"); set.add("set1","33"); set.add("set1","44"); Set<String> resultSet =stringRedisTemplate.opsForSet().members("set1"); stringRedisTemplate.opsForSet().add("set2", "1","2","3");//向指定key中存放set集合 Set<String> resultSet1 =stringRedisTemplate.opsForSet().members("set2"); log.info("resultSet:"+resultSet); log.info("resultSet1:"+resultSet1); #獲取ListOperations操作List數(shù)據(jù),list可以用來實(shí)現(xiàn)隊(duì)列。 //將數(shù)據(jù)添加到key對應(yīng)的現(xiàn)有數(shù)據(jù)的左邊 Long redisList = stringRedisTemplate.opsForList().leftPush("redisList", "3"); stringRedisTemplate.opsForList().leftPush("redisList", "4"); //將數(shù)據(jù)添加到key對應(yīng)的現(xiàn)有數(shù)據(jù)的右邊 Long size = stringRedisTemplate.opsForList().size("redisList"); //從左往右遍歷 String leftPop = stringRedisTemplate.opsForList().leftPop("redisList"); //從右往左遍歷 String rightPop = stringRedisTemplate.opsForList().rightPop("redisList"); //查詢?nèi)吭? List<String> range = stringRedisTemplate.opsForList().range("redisList", 0, -1); //查詢前三個(gè)元素 List<String> range1 = stringRedisTemplate.opsForList().range("redisList", 0, 3); //從左往右刪除list中元素A (1:從左往右 -1:從右往左 0:刪除全部) Long remove = stringRedisTemplate.opsForList().remove("key", 1, "A"); log.info("redisList----"+redisList); log.info("size----"+size); log.info("leftPop----"+leftPop); log.info("rightPop----"+rightPop); log.info("range----"+range); log.info("range1----"+range1); log.info("remove----"+remove); //判斷key對應(yīng)的map中是否存在hash Boolean aBoolean = stringRedisTemplate.opsForHash().hasKey("hash", "hash1"); //往key對應(yīng)的map中新增(key1,value1) stringRedisTemplate.opsForHash().put("hash", "hash1", "value1"); //獲取key對應(yīng)的map中hash1的值 Object o = stringRedisTemplate.opsForHash().get("hash", "hash1"); //刪除key對應(yīng)的map中多個(gè)子hash(可變參數(shù)) Long delete = stringRedisTemplate.opsForHash().delete("hash", "key1", "key2", "key3"); //獲取hash對應(yīng)的map Map<Object, Object> hash = stringRedisTemplate.opsForHash().entries("hash"); //獲取hash對應(yīng)的map中全部子hash集合 Set<Object> hash1 = stringRedisTemplate.opsForHash().keys("hash"); //獲取hash對應(yīng)的map中全部value集合 List<Object> hash2 = stringRedisTemplate.opsForHash().values("hash"); #刪除鍵 Boolean key = stringRedisTemplate.delete("key"); #數(shù)字加x Long count = stringRedisTemplate.boundValueOps("count").increment(1);//val +1 #獲取過期時(shí)間,不設(shè)的話為-1 Long time = stringRedisTemplate.getExpire("count")
Spring boot多數(shù)據(jù)源配置
配置一個(gè)1號庫,一個(gè)4號庫
添加依賴
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
修改application.properties配置文件
#1號庫 spring.redis.redis-onedb.database=0 spring.redis.redis-onedb.hostName=192.168.90.42 spring.redis.redis-onedb.port=9110 spring.redis.redis-onedb.timeout=5000 #4號庫 spring.redis.redis-fourdb.database=4 spring.redis.redis-fourdb.hostName=192.168.90.42 spring.redis.redis-fourdb.port=9110 spring.redis.redis-fourdb.timeout=5000
創(chuàng)建RedisConfig.java文件
@Configuration public class RedisConfig { @Bean @ConfigurationProperties(prefix = "spring.redis.lettuce.pool") @Scope(value = "prototype") public GenericObjectPoolConfig redisPool(){ return new GenericObjectPoolConfig(); } @Bean @ConfigurationProperties(prefix = "spring.redis.redis-fourdb") public RedisStandaloneConfiguration redisConfigA(){ return new RedisStandaloneConfiguration(); } @Bean @ConfigurationProperties(prefix = "spring.redis.redis-onedb") public RedisStandaloneConfiguration redisConfigB(){ return new RedisStandaloneConfiguration(); } @Primary @Bean public LettuceConnectionFactory factoryA(GenericObjectPoolConfig config, RedisStandaloneConfiguration redisConfigA){ LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder() .poolConfig(config).commandTimeout(Duration.ofMillis(config.getMaxWaitMillis())).build(); return new LettuceConnectionFactory(redisConfigA, clientConfiguration); } @Bean public LettuceConnectionFactory factoryB(GenericObjectPoolConfig config, RedisStandaloneConfiguration redisConfigB){ LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder() .poolConfig(config).commandTimeout(Duration.ofMillis(config.getMaxWaitMillis())).build(); return new LettuceConnectionFactory(redisConfigB, clientConfiguration); } @Bean(name = "fourRedis") public StringRedisTemplate redisBusTemplate(@Qualifier("factoryA") LettuceConnectionFactory factoryA){ StringRedisTemplate template = getRedisTemplate(); template.setConnectionFactory(factoryA); return template; } @Bean(name = "oneRedis") public StringRedisTemplate redisLoginTemplate(@Qualifier("factoryB")LettuceConnectionFactory factoryB){ StringRedisTemplate template = getRedisTemplate(); template.setConnectionFactory(factoryB); return template; } private StringRedisTemplate getRedisTemplate(){ StringRedisTemplate template = new StringRedisTemplate(); template.setValueSerializer(new GenericFastJsonRedisSerializer()); template.setValueSerializer(new StringRedisSerializer()); return template; } }
在需要使用的類,注入就可以使用
@Resource(name = "oneRedis") private StringRedisTemplate oneRedis; @Resource(name = "fourRedis") private StringRedisTemplate fourRedis;
StringRedisTemplate實(shí)現(xiàn)事務(wù)
stringRedisTemplate.setEnableTransactionSupport(true); try { stringRedisTemplate.multi();//開啟事務(wù) stringRedisTemplate.opsForValue().increment("count", 1); stringRedisTemplate.opsForValue().increment("count1", 2); //提交 stringRedisTemplate.exec(); }catch (Exception e){ log.error(e.getMessage(), e); //開啟回滾 stringRedisTemplate.discard(); }
注意:StringRedisTemplate開啟事務(wù)之后,不釋放連接。如果我們使用Spring事務(wù)管理不存在這個(gè)問題
StringRedisTemplate實(shí)現(xiàn)樂觀鎖
redisTemplate.watch("key"); // 1 redisTemplate.multi(); redisTemplate.boundValueOps("key").set(""+id); List<Object> list= redisTemplate.exec(); System.out.println(list); if(list != null ){ //操作成功 System.out.println(id+"操作成功"); }else{ //操作失敗 System.out.println(id+"操作失敗"); }
StringRedisTemplate實(shí)現(xiàn)pipe管道
StringRedisTemplate實(shí)現(xiàn)分布式鎖
String lockKey = "key"; String lockValue = lockKey+System.currentTimeMillis(); // value需要記住用于解鎖 while (true){ Boolean ifPresent = stringRedisTemplate.opsForValue(). setIfAbsent("redis-lock:" + lockKey, lockValue, 3, TimeUnit.SECONDS); if (ifPresent){ log.info("get redis-lock success"); break; } } //解鎖 String lockKey = "key"; String lockValue = lockKey + System.currentTimeMillis(); boolean result = false; // value需要記住用于解鎖 stringRedisTemplate.watch("redis-lock:" + lockKey); String value = stringRedisTemplate.opsForValue().get("redis-lock:" + lockKey); if (null == value){ result = true; }else if (value.equals(lockValue)) { stringRedisTemplate.delete("redis-lock:" + lockKey); result = true; } stringRedisTemplate.unwatch();
Redis緩存擊穿、穿透和雪崩
- 緩存擊穿,是指一個(gè)key非常熱點(diǎn),在不停的扛著大并發(fā),大并發(fā)集中對這一個(gè)點(diǎn)進(jìn)行訪問,當(dāng)這個(gè)key在失效的瞬間,持續(xù)的大并發(fā)就穿破緩存,直接請求數(shù)據(jù)庫,就像在一個(gè)屏障上鑿開了一個(gè)洞
- 緩存穿透,是指查詢一個(gè)數(shù)據(jù)庫一定不存在的數(shù)據(jù)。正常的使用緩存流程大致是,數(shù)據(jù)查詢先進(jìn)行緩存查詢,如果key不存在或者key已經(jīng)過期,再對數(shù)據(jù)庫進(jìn)行查詢,并把查詢到的對象,放進(jìn)緩存。如果數(shù)據(jù)庫查詢對象為空,則不放進(jìn)緩存。解決辦法是即使查出的對象為空,也放入緩存時(shí)間設(shè)短一點(diǎn)。
- 緩存雪崩,是指在某一個(gè)時(shí)間段,緩存集中過期失效。
以上就是使用StringRedisTemplate操作Redis方法詳解的詳細(xì)內(nèi)容,更多關(guān)于StringRedisTemplate操作Redis的資料請關(guān)注腳本之家其它相關(guān)文章!
- Java使用RedisTemplate如何根據(jù)前綴獲取key列表
- 使用redisTemplate從redis獲取所有數(shù)據(jù)
- SpringBoot整合Redis使用RedisTemplate和StringRedisTemplate
- Java中StringRedisTemplate和RedisTemplate的區(qū)別及使用方法
- Spring Boot中RedisTemplate的使用示例詳解
- Spring中RedisTemplate使用方法詳解
- Java使用RedisTemplate操作Redis遇到的坑
- Redis使用RedisTemplate導(dǎo)致key亂碼問題解決
- RedisTemplate的使用與注意事項(xiàng)小結(jié)
相關(guān)文章
Spring Boot中整合Spring Security并自定義驗(yàn)證代碼實(shí)例
本篇文章主要介紹了Spring Boot中整合Spring Security并自定義驗(yàn)證代碼實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04解析Mybatis的insert方法返回?cái)?shù)字-2147482646的解決
這篇文章主要介紹了解析Mybatis的insert方法返回?cái)?shù)字-2147482646的解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04SpringBoot 整合 Shiro 密碼登錄與郵件驗(yàn)證碼登錄功能(多 Realm 認(rèn)證)
這篇文章主要介紹了SpringBoot 整合 Shiro 密碼登錄與郵件驗(yàn)證碼登錄(多 Realm 認(rèn)證),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02用Java連接sqlserver數(shù)據(jù)庫時(shí)候幾個(gè)jar包的區(qū)別分析
這篇文章主要介紹了用Java連接sqlserver數(shù)據(jù)庫時(shí)候幾個(gè)jar包的區(qū)別分析,需要的朋友可以參考下2014-10-10SpringBoot中FailureAnalyzer的使用詳解
這篇文章主要介紹了SpringBoot中FailureAnalyzer的使用詳解,FailureAnalyzer攔截啟動(dòng)時(shí)異常,將異常轉(zhuǎn)換成更加易讀的信息并包裝成org.springframework.boot.diagnostics.FailureAnalysis對象,監(jiān)控應(yīng)用啟動(dòng)過程,需要的朋友可以參考下2023-12-12java利用jieba進(jìn)行分詞的實(shí)現(xiàn)
本文主要介紹了在Java中使用jieba-analysis庫進(jìn)行分詞,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03