日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

hash redis springboot_Redis常见的工作场景使用实战,Redisson分布式锁的实现

發布時間:2023/12/19 数据库 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hash redis springboot_Redis常见的工作场景使用实战,Redisson分布式锁的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

迎關注我的頭條號:Wooola,10 年 Java 軟件開發及架構設計經驗,專注于 Java、Go 語言、微服務架構,致力于每天分享原創文章、快樂編碼和開源技術。

前言

本項目基于springboot+ spring-boot-starter-data-redis+redisson

簡單的redis demo可以參考:SpringBoot整合redis

https://www.jianshu.com/p/8e71737a1101

github地址:

Redisson:https://github.com/weiess/redis-and-Redisson.git

源碼地址:https://github.com/weiess/redis-and-Redisson.git

redis大家工作的時候都很多,筆者根據自己經驗總結下redis的幾個數據類型,常用場景,也歡迎大家留言總結自己的經驗。

hash

hash在redis里可以存儲對象,當然string也可以,只不過hash相比較string,效率更高一點,而且功能也很強大,可以實現簡單的購物車:
下面先給大家看下簡單的存儲對象hash實現:

/* * hash實現存儲對象 * */ @Test public void testHsetpojo(){ User user = new User(); user.setId(123); user.setAge(20); user.setAddr("北京"); user.setName("yang"); Map map = BeanUtils.beanToMap(user); String key = "user"; redisUtil.hmset(key,map); System.out.println(redisUtil.hmget(key)); System.out.println("id="+redisUtil.hget(key,"id")); String key2 = "user:"+user.getId(); redisUtil.hmset(key2,map); System.out.println(redisUtil.hmget(key2)); }

這里的redisUtil是筆者封好的工具類,源碼在文章最底下。

hash存儲對象的時候可以把user當作key,例如代碼中的key,因為hash是 key item value三種結構,可以把后面的item和value看成一個map,這樣結構就是key map,方便理解。

實際項目中可以給key加個標示符,比如key = userId:a123456,這個大家可以根據項目來定義。

可以用hash實現購物車功能:
例如:

hash.jpg

代碼如下:

/* * hash實現購物車 * */ @Test public void testcar(){ String key ="carUser:123456"; redisUtil.del(key); Map map = new HashMap(); map.put("book:a11111",1); map.put("book:a11112",2); map.put("book:a11113",3); boolean b = redisUtil.hmset(key,map); System.out.println("key = "+redisUtil.hmget(key)); //增加book:a11111的數量 redisUtil.hincr(key,"book:a11111",1); System.out.println(redisUtil.hmget(key)); //減少book:a11112的數量 redisUtil.hincr(key,"book:a11112",-3); //或者redisUtil.hdecr(key,"book:a11111",1); System.out.println(redisUtil.hmget(key)); //獲取所有key1的field的值 System.out.println("hegetall="+redisUtil.hmget(key)); //獲取key下面的map數量 System.out.println("length="+redisUtil.hlen(key)); //刪除某個key下的map redisUtil.hdel(key,"book:a11112"); System.out.println(redisUtil.hmget(key)); }

hash里的key就是當前用戶的購物車,map就是商品(map里的key是商品id,map的v是數量)
功能實現注釋都有。注意這里的減操作是可以為負數的,所以大家一定要注意判斷負數的情況。

list

常見的list可以分為下面三個數據結構方便大家理解:

stack(棧)= LPUSH + LPOP Queue(隊列)= LPUSH + RPOP BlockingMQ(阻塞隊列)= LPUSH + BRPOP

@Test public void testList(){ String key = "a123456"; redisUtil.del(key); String v1 = "aaaaa"; String v2 = "bbbbb"; String v3 = "ccccc"; List list = new ArrayList(); list.add(v1); list.add(v2); list.add(v3); boolean b1 = redisUtil.lSet(key,list); System.out.println(redisUtil.lGet(key,0,-1)); System.out.println(redisUtil.lGetIndex(key,0)); System.out.println(redisUtil.lpop(key)); System.out.println(redisUtil.rpop(key)); System.out.println(redisUtil.lGet(key,0,-1)); redisUtil.del(key); redisUtil.rpush(key,v1); System.out.println(redisUtil.lGet(key,0,-1)); redisUtil.rpush(key,v2); System.out.println(redisUtil.lGet(key,0,-1)); redisUtil.lpush(key,v3); System.out.println(redisUtil.lGet(key,0,-1)); }

實際工作中常用于消息推送,比如vx訂閱號推送,微博推送

代碼實現:

@Test public void testVX(){ String key = "VXuser:a123456"; redisUtil.del(key); String message1 = "a1"; String message2 = "b2"; String message3 = "c3"; //訂閱號a發表了一片文章,文章id是a1 redisUtil.lpush(key,message1); //訂閱號b發表了一片文章,文章id是b2 redisUtil.lpush(key,message2); //訂閱號b發表了一片文章,文章id是c3 redisUtil.lpush(key,message3); //用戶獲取 System.out.println(redisUtil.lGet(key,0,-1)); }

比如user:a23456訂閱了這個訂閱號a,訂閱號a寫了一片內容,只需要加入user:a123456的隊列中,user就能查看到,這里的redisUtil.lGet(key,0,-1)表示獲取key下的所有v。

set

set常用于一些數學運算,他有求交集,并集,差集的功能:

@Test public void testset(){ String key1 = "a1"; redisUtil.del(key1); String key2 = "a2"; redisUtil.del(key2); redisUtil.sSet(key1,1,2,3,4,5); System.out.println("key1="+redisUtil.sGet(key1)); redisUtil.sSet(key2,1,2,5,6,7); System.out.println("key1="+redisUtil.sGet(key2)); //獲取key的數量 System.out.println("length="+redisUtil.sGetSetSize(key1)); //取key1和key2的交集 System.out.println("交集="+redisUtil.sIntersect(key1,key2)); //取key1和key2的差集 System.out.println("差集="+redisUtil.sDifference(key1,key2)); //取key1和key2的并集 System.out.println("并集="+redisUtil.sUnion(key1,key2)); //取key1的隨機一個數 System.out.println("隨機數="+redisUtil.sRandom(key1)); System.out.println("key1="+redisUtil.sGet(key1)); //取key1的隨機一個數,并且這個值在key中刪除 System.out.println("隨機數="+redisUtil.spop(key1)); System.out.println("key1="+redisUtil.sGet(key1)); }

實際工作中可以實現抽獎,共同關注,推薦好友等功能:

@Test public void testSet2(){ String key ="act:123456"; redisUtil.del(key); long l = redisUtil.sSet(key,"a1","a2","a3","a4","a5"); System.out.println(redisUtil.sGet(key)); //抽獎 System.out.println(redisUtil.spop(key)); String user1 = "vxuser:a123456"; String user2 = "vxuser:b123456"; String user3 = "vxuser:c123456"; String user4 = "vxuser:d123456"; String user5 = "vxuser:e123456"; String user6 = "vxuser:f123456"; redisUtil.del("gzuser1"); redisUtil.del("gzuser2"); //gzuser1關注user2,user3,user6 redisUtil.sSet("gzuser1",user2,user3,user6); //gzuser2關注user1,user3,user4,user5 redisUtil.sSet("gzuser2",user1,user3,user4,user5); //共同好友 System.out.println("共同好友"+redisUtil.sIntersect("gzuser1","gzuser2")); //你關注的好友也關注了他 Set set = redisUtil.sUnion(user1,user2); //這里取并集,放在中間表bj里 for (String s:set){ redisUtil.sSet("bj",s); } System.out.println(redisUtil.sGet("bj")); System.out.println("你關注的好友也關注了他"+redisUtil.sDifference("bj","gzuser1")); }

zset

zset相比較set一個有序,一個無序,具體功能大同小異,我就不多說。

string

簡單的string基本功能我就不多說了,這里要說的是分布式常見的setnx命令實現分布式鎖:

setnx命令其實表示『SET if Not eXists』(如果不存在,則 SET)的簡寫。設置成功,返回 1 ;設置失敗,返回 0 。
如果set 的key已經在redis里了,你再setnx,就會失敗,但是你繼續用set命令,是會覆蓋當前的key,且返回成功。

/* * setnx 實現最簡單的分布式鎖 * */ @Test public void setlock() { DefaultRedisScript script = new DefaultRedisScript(); script.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/deleteLua.lua"))); script.setResultType(Long.class); String key ="product:001"; String value = Thread.currentThread().getId()+""; try { boolean result = redisUtil.setnx(key,value,100); if(!result){ System.out.println("系統繁忙中"); } else { System.out.println("這里是你業務代碼"); } }catch (Exception e){ e.printStackTrace(); }finally { Object result = redisUtil.execute(script,Collections.singletonList(key),value); System.out.println(result);// if (value.equals(redisUtil.get(key))){// redisUtil.del(key); } } }

這是最簡單的分布式鎖實現,我給大家簡單解釋下:
首先,DefaultRedisScript這個類是為了讀取lua腳本,這里筆者的finally代碼塊用了lua腳本刪除redis的key,其實

Object result = redisUtil.execute(script,Collections.singletonList(key),value);

這行代碼等價于下面這行代碼

if (value.equals(redisUtil.get(key))){ redisUtil.del(key); }

為什么要用lua腳本呢,更多的是為了原子性,如果用if操作,要執行兩部,在大型的環境下很容易出問題,而lua腳本就不會,他把兩個步驟合成一個步驟去執行,這樣保證原子性。

總結

以上是生活随笔為你收集整理的hash redis springboot_Redis常见的工作场景使用实战,Redisson分布式锁的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。