国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于Spring boot和Mybatis外賣(mài)項(xiàng)目瑞吉外賣(mài)Day9-Redis的快速入門(mén)

這篇具有很好參考價(jià)值的文章主要介紹了基于Spring boot和Mybatis外賣(mài)項(xiàng)目瑞吉外賣(mài)Day9-Redis的快速入門(mén)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

4.Redis常見(jiàn)命令

4.1 Redis數(shù)據(jù)結(jié)構(gòu)介紹

Redis是一個(gè)key-value的數(shù)據(jù)庫(kù),key一般是String類型,不過(guò)value的類型多種多樣:

貼心小建議:命令不要死記,學(xué)會(huì)查詢就好啦

Redis為了方便我們學(xué)習(xí),將操作不同數(shù)據(jù)類型的命令也做了分組,在官網(wǎng)( https://redis.io/commands )可以查看到不同的命令:

當(dāng)然我們也可以通過(guò)Help命令來(lái)幫助我們?nèi)ゲ榭疵?/p>

4.2 Redis 通用命令

通用指令是部分?jǐn)?shù)據(jù)類型的,都可以使用的指令,常見(jiàn)的有:

  • KEYS:查看符合模板的所有key
  • DEL:刪除一個(gè)指定的key
  • EXISTS:判斷key是否存在
  • EXPIRE:給一個(gè)key設(shè)置有效期,有效期到期時(shí)該key會(huì)被自動(dòng)刪除
  • TTL:查看一個(gè)KEY的剩余有效期

通過(guò)help [command] 可以查看一個(gè)命令的具體用法,例如:

課堂代碼如下

  • KEYS
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379>

# 查詢以a開(kāi)頭的key
127.0.0.1:6379> keys a*
1) "age"
127.0.0.1:6379>

貼心小提示:在生產(chǎn)環(huán)境下,不推薦使用keys 命令,因?yàn)檫@個(gè)命令在key過(guò)多的情況下,效率不高

  • DEL
127.0.0.1:6379> help del

  DEL key [key ...]
  summary: Delete a key
  since: 1.0.0
  group: generic

127.0.0.1:6379> del name #刪除單個(gè)
(integer) 1  #成功刪除1個(gè)

127.0.0.1:6379> keys *
1) "age"

127.0.0.1:6379> MSET k1 v1 k2 v2 k3 v3 #批量添加數(shù)據(jù)
OK

127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
4) "age"

127.0.0.1:6379> del k1 k2 k3 k4
(integer) 3   #此處返回的是成功刪除的key,由于redis中只有k1,k2,k3 所以只成功刪除3個(gè),最終返回
127.0.0.1:6379>

127.0.0.1:6379> keys * #再查詢?nèi)康膋ey
1) "age"	#只剩下一個(gè)了
127.0.0.1:6379>

貼心小提示:同學(xué)們?cè)诳截惔a的時(shí)候,只需要拷貝對(duì)應(yīng)的命令哦~

  • EXISTS
127.0.0.1:6379> help EXISTS

  EXISTS key [key ...]
  summary: Determine if a key exists
  since: 1.0.0
  group: generic

127.0.0.1:6379> exists age
(integer) 1

127.0.0.1:6379> exists name
(integer) 0
  • EXPIRE

貼心小提示:內(nèi)存非常寶貴,對(duì)于一些數(shù)據(jù),我們應(yīng)當(dāng)給他一些過(guò)期時(shí)間,當(dāng)過(guò)期時(shí)間到了之后,他就會(huì)自動(dòng)被刪除~

127.0.0.1:6379> expire age 10
(integer) 1

127.0.0.1:6379> ttl age
(integer) 8

127.0.0.1:6379> ttl age
(integer) 6

127.0.0.1:6379> ttl age
(integer) -2

127.0.0.1:6379> ttl age
(integer) -2  #當(dāng)這個(gè)key過(guò)期了,那么此時(shí)查詢出來(lái)就是-2 

127.0.0.1:6379> keys *
(empty list or set)

127.0.0.1:6379> set age 10 #如果沒(méi)有設(shè)置過(guò)期時(shí)間
OK

127.0.0.1:6379> ttl age
(integer) -1  # ttl的返回值就是-1

4.3 Redis命令-String命令

String類型,也就是字符串類型,是Redis中最簡(jiǎn)單的存儲(chǔ)類型。

其value是字符串,不過(guò)根據(jù)字符串的格式不同,又可以分為3類:

  • string:普通字符串
  • int:整數(shù)類型,可以做自增.自減操作
  • float:浮點(diǎn)類型,可以做自增.自減操作

String的常見(jiàn)命令有:

  • SET:添加或者修改已經(jīng)存在的一個(gè)String類型的鍵值對(duì)
  • GET:根據(jù)key獲取String類型的value
  • MSET:批量添加多個(gè)String類型的鍵值對(duì)
  • MGET:根據(jù)多個(gè)key獲取多個(gè)String類型的value
  • INCR:讓一個(gè)整型的key自增1
  • INCRBY:讓一個(gè)整型的key自增并指定步長(zhǎng),例如:incrby num 2 讓num值自增2
  • INCRBYFLOAT:讓一個(gè)浮點(diǎn)類型的數(shù)字自增并指定步長(zhǎng)
  • SETNX:添加一個(gè)String類型的鍵值對(duì),前提是這個(gè)key不存在,否則不執(zhí)行
  • SETEX:添加一個(gè)String類型的鍵值對(duì),并且指定有效期

貼心小提示:以上命令除了INCRBYFLOAT 都是常用命令

  • SET 和GET: 如果key不存在則是新增,如果存在則是修改
127.0.0.1:6379> set name Rose  //原來(lái)不存在
OK

127.0.0.1:6379> get name 
"Rose"

127.0.0.1:6379> set name Jack //原來(lái)存在,就是修改
OK

127.0.0.1:6379> get name
"Jack"
  • MSET和MGET
127.0.0.1:6379> MSET k1 v1 k2 v2 k3 v3
OK

127.0.0.1:6379> MGET name age k1 k2 k3
1) "Jack" //之前存在的name
2) "10"   //之前存在的age
3) "v1"
4) "v2"
5) "v3"
  • INCR和INCRBY和DECY
127.0.0.1:6379> get age 
"10"

127.0.0.1:6379> incr age //增加1
(integer) 11
    
127.0.0.1:6379> get age //獲得age
"11"

127.0.0.1:6379> incrby age 2 //一次增加2
(integer) 13 //返回目前的age的值
    
127.0.0.1:6379> incrby age 2
(integer) 15
    
127.0.0.1:6379> incrby age -1 //也可以增加負(fù)數(shù),相當(dāng)于減
(integer) 14
    
127.0.0.1:6379> incrby age -2 //一次減少2個(gè)
(integer) 12
    
127.0.0.1:6379> DECR age //相當(dāng)于 incr 負(fù)數(shù),減少正常用法
(integer) 11
    
127.0.0.1:6379> get age 
"11"

  • SETNX
127.0.0.1:6379> help setnx

  SETNX key value
  summary: Set the value of a key, only if the key does not exist
  since: 1.0.0
  group: string

127.0.0.1:6379> set name Jack  //設(shè)置名稱
OK
127.0.0.1:6379> setnx name lisi //如果key不存在,則添加成功
(integer) 0
127.0.0.1:6379> get name //由于name已經(jīng)存在,所以lisi的操作失敗
"Jack"
127.0.0.1:6379> setnx name2 lisi //name2 不存在,所以操作成功
(integer) 1
127.0.0.1:6379> get name2 
"lisi"
  • SETEX
127.0.0.1:6379> setex name 10 jack
OK

127.0.0.1:6379> ttl name
(integer) 8

127.0.0.1:6379> ttl name
(integer) 7

127.0.0.1:6379> ttl name
(integer) 5

4.4 Redis命令-Key的層級(jí)結(jié)構(gòu)

Redis沒(méi)有類似MySQL中的Table的概念,我們?cè)撊绾螀^(qū)分不同類型的key呢?

例如,需要存儲(chǔ)用戶.商品信息到redis,有一個(gè)用戶id是1,有一個(gè)商品id恰好也是1,此時(shí)如果使用id作為key,那就會(huì)沖突了,該怎s么辦?

我們可以通過(guò)給key添加前綴加以區(qū)分,不過(guò)這個(gè)前綴不是隨便加的,有一定的規(guī)范:

Redis的key允許有多個(gè)單詞形成層級(jí)結(jié)構(gòu),多個(gè)單詞之間用’:'隔開(kāi),格式如下:

這個(gè)格式并非固定,也可以根據(jù)自己的需求來(lái)刪除或添加詞條。

例如我們的項(xiàng)目名稱叫 heima,有user和product兩種不同類型的數(shù)據(jù),我們可以這樣定義key:

  • user相關(guān)的key:heima:user:1

  • product相關(guān)的key:heima:product:1

如果Value是一個(gè)Java對(duì)象,例如一個(gè)User對(duì)象,則可以將對(duì)象序列化為JSON字符串后存儲(chǔ):

KEY VALUE
heima:user:1 {“id”:1, “name”: “Jack”, “age”: 21}
heima:product:1 {“id”:1, “name”: “小米11”, “price”: 4999}

一旦我們向redis采用這樣的方式存儲(chǔ),那么在可視化界面中,redis會(huì)以層級(jí)結(jié)構(gòu)來(lái)進(jìn)行存儲(chǔ),形成類似于這樣的結(jié)構(gòu),更加方便Redis獲取數(shù)據(jù)

4.5 Redis命令-Hash命令

Hash類型,也叫散列,其value是一個(gè)無(wú)序字典,類似于Java中的HashMap結(jié)構(gòu)。

String結(jié)構(gòu)是將對(duì)象序列化為JSON字符串后存儲(chǔ),當(dāng)需要修改對(duì)象某個(gè)字段時(shí)很不方便:

Hash結(jié)構(gòu)可以將對(duì)象中的每個(gè)字段獨(dú)立存儲(chǔ),可以針對(duì)單個(gè)字段做CRUD:

Hash類型的常見(jiàn)命令

  • HSET key field value:添加或者修改hash類型key的field的值
  • HGET key field:獲取一個(gè)hash類型key的field的值
  • HMSET:批量添加多個(gè)hash類型key的field的值
  • HMGET:批量獲取多個(gè)hash類型key的field的值
  • HGETALL:獲取一個(gè)hash類型的key中的所有的field和value
  • HKEYS:獲取一個(gè)hash類型的key中的所有的field
  • HINCRBY:讓一個(gè)hash類型key的字段值自增并指定步長(zhǎng)
  • HSETNX:添加一個(gè)hash類型的key的field值,前提是這個(gè)field不存在,否則不執(zhí)行

貼心小提示:哈希結(jié)構(gòu)也是我們以后實(shí)際開(kāi)發(fā)中常用的命令喲

  • HSET和HGET
127.0.0.1:6379> HSET heima:user:3 name Lucy//大key是 heima:user:3 小key是name,小value是Lucy
(integer) 1
127.0.0.1:6379> HSET heima:user:3 age 21// 如果操作不存在的數(shù)據(jù),則是新增
(integer) 1
127.0.0.1:6379> HSET heima:user:3 age 17 //如果操作存在的數(shù)據(jù),則是修改
(integer) 0
127.0.0.1:6379> HGET heima:user:3 name 
"Lucy"
127.0.0.1:6379> HGET heima:user:3 age
"17"
  • HMSET和HMGET
127.0.0.1:6379> HMSET heima:user:4 name HanMeiMei
OK
127.0.0.1:6379> HMSET heima:user:4 name LiLei age 20 sex man
OK
127.0.0.1:6379> HMGET heima:user:4 name age sex
1) "LiLei"
2) "20"
3) "man"
  • HGETALL
127.0.0.1:6379> HGETALL heima:user:4
1) "name"
2) "LiLei"
3) "age"
4) "20"
5) "sex"
6) "man"
  • HKEYS和HVALS
127.0.0.1:6379> HKEYS heima:user:4
1) "name"
2) "age"
3) "sex"
127.0.0.1:6379> HVALS heima:user:4
1) "LiLei"
2) "20"
3) "man"
  • HINCRBY
127.0.0.1:6379> HINCRBY  heima:user:4 age 2
(integer) 22
127.0.0.1:6379> HVALS heima:user:4
1) "LiLei"
2) "22"
3) "man"
127.0.0.1:6379> HINCRBY  heima:user:4 age -2
(integer) 20
  • HSETNX
127.0.0.1:6379> HSETNX heima:user4 sex woman
(integer) 1
127.0.0.1:6379> HGETALL heima:user:3
1) "name"
2) "Lucy"
3) "age"
4) "17"
127.0.0.1:6379> HSETNX heima:user:3 sex woman
(integer) 1
127.0.0.1:6379> HGETALL heima:user:3
1) "name"
2) "Lucy"
3) "age"
4) "17"
5) "sex"
6) "woman"

4.6 Redis命令-List命令

Redis中的List類型與Java中的LinkedList類似,可以看做是一個(gè)雙向鏈表結(jié)構(gòu)。既可以支持正向檢索和也可以支持反向檢索。

特征也與LinkedList類似:

  • 有序
  • 元素可以重復(fù)
  • 插入和刪除快
  • 查詢速度一般

常用來(lái)存儲(chǔ)一個(gè)有序數(shù)據(jù),例如:朋友圈點(diǎn)贊列表,評(píng)論列表等。

List的常見(jiàn)命令有:

  • LPUSH key element … :向列表左側(cè)插入一個(gè)或多個(gè)元素
  • LPOP key:移除并返回列表左側(cè)的第一個(gè)元素,沒(méi)有則返回nil
  • RPUSH key element … :向列表右側(cè)插入一個(gè)或多個(gè)元素
  • RPOP key:移除并返回列表右側(cè)的第一個(gè)元素
  • LRANGE key star end:返回一段角標(biāo)范圍內(nèi)的所有元素
  • BLPOP和BRPOP:與LPOP和RPOP類似,只不過(guò)在沒(méi)有元素時(shí)等待指定時(shí)間,而不是直接返回nil
  • LPUSH和RPUSH
127.0.0.1:6379> LPUSH users 1 2 3
(integer) 3
127.0.0.1:6379> RPUSH users 4 5 6
(integer) 6
  • LPOP和RPOP
127.0.0.1:6379> LPOP users
"3"
127.0.0.1:6379> RPOP users
"6"
  • LRANGE
127.0.0.1:6379> LRANGE users 1 2
1) "1"
2) "4"

4.7 Redis命令-Set命令

Redis的Set結(jié)構(gòu)與Java中的HashSet類似,可以看做是一個(gè)value為null的HashMap。因?yàn)橐彩且粋€(gè)hash表,因此具備與HashSet類似的特征:

  • 無(wú)序
  • 元素不可重復(fù)
  • 查找快
  • 支持交集.并集.差集等功能

Set類型的常見(jiàn)命令

  • SADD key member … :向set中添加一個(gè)或多個(gè)元素
  • SREM key member … : 移除set中的指定元素
  • SCARD key: 返回set中元素的個(gè)數(shù)
  • SISMEMBER key member:判斷一個(gè)元素是否存在于set中
  • SMEMBERS:獲取set中的所有元素
  • SINTER key1 key2 … :求key1與key2的交集
  • SDIFF key1 key2 … :求key1與key2的差集
  • SUNION key1 key2 …:求key1和key2的并集

例如兩個(gè)集合:s1和s2:

基于Spring boot和Mybatis外賣(mài)項(xiàng)目瑞吉外賣(mài)Day9-Redis的快速入門(mén)

求交集:SINTER s1 s2

求s1與s2的不同:SDIFF s1 s2

基于Spring boot和Mybatis外賣(mài)項(xiàng)目瑞吉外賣(mài)Day9-Redis的快速入門(mén)

具體命令

127.0.0.1:6379> sadd s1 a b c
(integer) 3
127.0.0.1:6379> smembers s1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> srem s1 a
(integer) 1
    
127.0.0.1:6379> SISMEMBER s1 a
(integer) 0
    
127.0.0.1:6379> SISMEMBER s1 b
(integer) 1
    
127.0.0.1:6379> SCARD s1
(integer) 2

案例

  • 將下列數(shù)據(jù)用Redis的Set集合來(lái)存儲(chǔ):
  • 張三的好友有:李四.王五.趙六
  • 李四的好友有:王五.麻子.二狗
  • 利用Set的命令實(shí)現(xiàn)下列功能:
  • 計(jì)算張三的好友有幾人
  • 計(jì)算張三和李四有哪些共同好友
  • 查詢哪些人是張三的好友卻不是李四的好友
  • 查詢張三和李四的好友總共有哪些人
  • 判斷李四是否是張三的好友
  • 判斷張三是否是李四的好友
  • 將李四從張三的好友列表中移除
127.0.0.1:6379> SADD zs lisi wangwu zhaoliu
(integer) 3
    
127.0.0.1:6379> SADD ls wangwu mazi ergou
(integer) 3
    
127.0.0.1:6379> SCARD zs
(integer) 3
    
127.0.0.1:6379> SINTER zs ls
1) "wangwu"
    
127.0.0.1:6379> SDIFF zs ls
1) "zhaoliu"
2) "lisi"
    
127.0.0.1:6379> SUNION zs ls
1) "wangwu"
2) "zhaoliu"
3) "lisi"
4) "mazi"
5) "ergou"
    
127.0.0.1:6379> SISMEMBER zs lisi
(integer) 1
    
127.0.0.1:6379> SISMEMBER ls zhangsan
(integer) 0
    
127.0.0.1:6379> SREM zs lisi
(integer) 1
    
127.0.0.1:6379> SMEMBERS zs
1) "zhaoliu"
2) "wangwu"

4.8 Redis命令-SortedSet類型

Redis的SortedSet是一個(gè)可排序的set集合,與Java中的TreeSet有些類似,但底層數(shù)據(jù)結(jié)構(gòu)卻差別很大。SortedSet中的每一個(gè)元素都帶有一個(gè)score屬性,可以基于score屬性對(duì)元素排序,底層的實(shí)現(xiàn)是一個(gè)跳表(SkipList)加 hash表。

SortedSet具備下列特性:

  • 可排序
  • 元素不重復(fù)
  • 查詢速度快

因?yàn)镾ortedSet的可排序特性,經(jīng)常被用來(lái)實(shí)現(xiàn)排行榜這樣的功能。

SortedSet的常見(jiàn)命令有:

  • ZADD key score member:添加一個(gè)或多個(gè)元素到sorted set ,如果已經(jīng)存在則更新其score值
  • ZREM key member:刪除sorted set中的一個(gè)指定元素
  • ZSCORE key member : 獲取sorted set中的指定元素的score值
  • ZRANK key member:獲取sorted set 中的指定元素的排名
  • ZCARD key:獲取sorted set中的元素個(gè)數(shù)
  • ZCOUNT key min max:統(tǒng)計(jì)score值在給定范圍內(nèi)的所有元素的個(gè)數(shù)
  • ZINCRBY key increment member:讓sorted set中的指定元素自增,步長(zhǎng)為指定的increment值
  • ZRANGE key min max:按照score排序后,獲取指定排名范圍內(nèi)的元素
  • ZRANGEBYSCORE key min max:按照score排序后,獲取指定score范圍內(nèi)的元素
  • ZDIFF.ZINTER.ZUNION:求差集.交集.并集

注意:所有的排名默認(rèn)都是升序,如果要降序則在命令的Z后面添加REV即可,例如:

  • 升序獲取sorted set 中的指定元素的排名:ZRANK key member
  • 降序獲取sorted set 中的指定元素的排名:ZREVRANK key memeber

5.Redis的Java客戶端-Jedis

在Redis官網(wǎng)中提供了各種語(yǔ)言的客戶端,地址:https://redis.io/docs/clients/

基于Spring boot和Mybatis外賣(mài)項(xiàng)目瑞吉外賣(mài)Day9-Redis的快速入門(mén)

其中Java客戶端也包含很多:

標(biāo)記為?的就是推薦使用的java客戶端,包括:

  • Jedis和Lettuce:這兩個(gè)主要是提供了Redis命令對(duì)應(yīng)的API,方便我們操作Redis,而SpringDataRedis又對(duì)這兩種做了抽象和封裝,因此我們后期會(huì)直接以SpringDataRedis來(lái)學(xué)習(xí)。
  • Redisson:是在Redis基礎(chǔ)上實(shí)現(xiàn)了分布式的可伸縮的java數(shù)據(jù)結(jié)構(gòu),例如Map.Queue等,而且支持跨進(jìn)程的同步機(jī)制:Lock.Semaphore等待,比較適合用來(lái)實(shí)現(xiàn)特殊的功能需求。

5.1 Jedis快速入門(mén)

入門(mén)案例詳細(xì)步驟

案例分析:

0)創(chuàng)建工程:

1)引入依賴:

<!--jedis-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.7.0</version>
</dependency>
<!--單元測(cè)試-->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.7.0</version>
    <scope>test</scope>
</dependency>

2)建立連接

新建一個(gè)單元測(cè)試類,內(nèi)容如下:

private Jedis jedis;

@BeforeEach
void setUp() {
    // 1.建立連接
    // jedis = new Jedis("192.168.150.101", 6379);
    jedis = JedisConnectionFactory.getJedis();
    // 2.設(shè)置密碼
    jedis.auth("123321");
    // 3.選擇庫(kù)
    jedis.select(0);
}

3)測(cè)試:

@Test
void testString() {
    // 存入數(shù)據(jù)
    String result = jedis.set("name", "虎哥");
    System.out.println("result = " + result);
    // 獲取數(shù)據(jù)
    String name = jedis.get("name");
    System.out.println("name = " + name);
}

@Test
void testHash() {
    // 插入hash數(shù)據(jù)
    jedis.hset("user:1", "name", "Jack");
    jedis.hset("user:1", "age", "21");

    // 獲取
    Map<String, String> map = jedis.hgetAll("user:1");
    System.out.println(map);
}

4)釋放資源

@AfterEach
void tearDown() {
    if (jedis != null) {
        jedis.close();
    }
}

5.2 Jedis連接池

Jedis本身是線程不安全的,并且頻繁的創(chuàng)建和銷(xiāo)毀連接會(huì)有性能損耗,因此我們推薦大家使用Jedis連接池代替Jedis的直連方式

有關(guān)池化思想,并不僅僅是這里會(huì)使用,很多地方都有,比如說(shuō)我們的數(shù)據(jù)庫(kù)連接池,比如我們tomcat中的線程池,這些都是池化思想的體現(xiàn)。

5.2.1.創(chuàng)建Jedis的連接池
public class JedisConnectionFacotry {

     private static final JedisPool jedisPool;

     static {
         //配置連接池
         JedisPoolConfig poolConfig = new JedisPoolConfig();
         poolConfig.setMaxTotal(8);
         poolConfig.setMaxIdle(8);
         poolConfig.setMinIdle(0);
         poolConfig.setMaxWaitMillis(1000);
         //創(chuàng)建連接池對(duì)象
         jedisPool = new JedisPool(poolConfig,
                 "192.168.150.101",6379,1000,"123321");
     }

     public static Jedis getJedis(){
          return jedisPool.getResource();
     }
}

代碼說(shuō)明:

  • 1) JedisConnectionFacotry:工廠設(shè)計(jì)模式是實(shí)際開(kāi)發(fā)中非常常用的一種設(shè)計(jì)模式,我們可以使用工廠,去降低代的耦合,比如Spring中的Bean的創(chuàng)建,就用到了工廠設(shè)計(jì)模式

  • 2)靜態(tài)代碼塊:隨著類的加載而加載,確保只能執(zhí)行一次,我們?cè)诩虞d當(dāng)前工廠類的時(shí)候,就可以執(zhí)行static的操作完成對(duì) 連接池的初始化

  • 3)最后提供返回連接池中連接的方法.

5.2.2.改造原始代碼

代碼說(shuō)明:

1.在我們完成了使用工廠設(shè)計(jì)模式來(lái)完成代碼的編寫(xiě)之后,我們?cè)讷@得連接時(shí),就可以通過(guò)工廠來(lái)獲得。

,而不用直接去new對(duì)象,降低耦合,并且使用的還是連接池對(duì)象。

2.當(dāng)我們使用了連接池后,當(dāng)我們關(guān)閉連接其實(shí)并不是關(guān)閉,而是將Jedis還回連接池的。

    @BeforeEach
    void setUp(){
        //建立連接
        /*jedis = new Jedis("127.0.0.1",6379);*/
        jedis = JedisConnectionFacotry.getJedis();
         //選擇庫(kù)
        jedis.select(0);
    }

   @AfterEach
    void tearDown() {
        if (jedis != null) {
            jedis.close();
        }
    }

3.2.SpringDataRedis客戶端

SpringData是Spring中數(shù)據(jù)操作的模塊,包含對(duì)各種數(shù)據(jù)庫(kù)的集成,其中對(duì)Redis的集成模塊就叫做SpringDataRedis,官網(wǎng)地址:https://spring.io/projects/spring-data-redis

  • 提供了對(duì)不同Redis客戶端的整合(Lettuce和Jedis)
  • 提供了RedisTemplate統(tǒng)一API來(lái)操作Redis
  • 支持Redis的發(fā)布訂閱模型
  • 支持Redis哨兵和Redis集群
  • 支持基于Lettuce的響應(yīng)式編程
  • 支持基于JDK、JSON、字符串、Spring對(duì)象的數(shù)據(jù)序列化及反序列化
  • 支持基于Redis的JDKCollection實(shí)現(xiàn)

SpringDataRedis中提供了RedisTemplate工具類,其中封裝了各種對(duì)Redis的操作。并且將不同數(shù)據(jù)類型的操作API封裝到了不同的類型中:

6.1.快速入門(mén)

SpringBoot已經(jīng)提供了對(duì)SpringDataRedis的支持,使用非常簡(jiǎn)單。

首先,新建一個(gè)maven項(xiàng)目,然后按照下面步驟執(zhí)行:

6.1.1引入依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.heima</groupId>
    <artifactId>redis-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>redis-demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!--redis依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--common-pool-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!--Jackson依賴-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

6.1.2配置Redis

spring:
  redis:
    host: 192.168.150.101
    port: 6379
    password: 123321
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 100ms

6.1.3注入RedisTemplate

因?yàn)橛辛薙pringBoot的自動(dòng)裝配,我們可以拿來(lái)就用:

@SpringBootTest
class RedisStringTests {

    @Autowired
    private RedisTemplate redisTemplate;
}

6.1.4編寫(xiě)測(cè)試

@SpringBootTest
class RedisStringTests {

    @Autowired
    private RedisTemplate edisTemplate;

    @Test
    void testString() {
        // 寫(xiě)入一條String數(shù)據(jù)
        redisTemplate.opsForValue().set("name", "虎哥");
        // 獲取string數(shù)據(jù)
        Object name = stringRedisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);
    }
}

6.2自定義序列化

RedisTemplate可以接收任意Object作為值寫(xiě)入Redis

只不過(guò)寫(xiě)入前會(huì)把Object序列化為字節(jié)形式,默認(rèn)是采用JDK序列化

缺點(diǎn):

  • 可讀性差
  • 內(nèi)存占用較大

我們可以自定義RedisTemplate的序列化方式,代碼如下:

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){
        // 創(chuàng)建RedisTemplate對(duì)象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 設(shè)置連接工廠
        template.setConnectionFactory(connectionFactory);
        // 創(chuàng)建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = 
            							new GenericJackson2JsonRedisSerializer();
        // 設(shè)置Key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // 設(shè)置Value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
        // 返回
        return template;
    }
}

這里采用了JSON序列化來(lái)代替默認(rèn)的JDK序列化方式。最終結(jié)果如圖:

整體可讀性有了很大提升,并且能將Java對(duì)象自動(dòng)的序列化為JSON字符串,并且查詢時(shí)能自動(dòng)把JSON反序列化為Java對(duì)象。不過(guò),其中記錄了序列化時(shí)對(duì)應(yīng)的class名稱,目的是為了查詢時(shí)實(shí)現(xiàn)自動(dòng)反序列化。這會(huì)帶來(lái)額外的內(nèi)存開(kāi)銷(xiāo)。

6.3.StringRedisTemplate

為了節(jié)省內(nèi)存空間,我們可以不使用JSON序列化器來(lái)處理value,而是統(tǒng)一使用String序列化器,要求只能存儲(chǔ)String類型的key和value。當(dāng)需要存儲(chǔ)Java對(duì)象時(shí),手動(dòng)完成對(duì)象的序列化和反序列化。

因?yàn)榇嫒牒妥x取時(shí)的序列化及反序列化都是我們自己實(shí)現(xiàn)的,SpringDataRedis就不會(huì)將class信息寫(xiě)入Redis了。

這種用法比較普遍,因此SpringDataRedis就提供了RedisTemplate的子類:StringRedisTemplate,它的key和value的序列化方式默認(rèn)就是String方式。

省去了我們自定義RedisTemplate的序列化方式的步驟,而是直接使用:

@Autowired
private StringRedisTemplate stringRedisTemplate;
// JSON序列化工具
private static final ObjectMapper mapper = new ObjectMapper();

@Test
void testSaveUser() throws JsonProcessingException {
    // 創(chuàng)建對(duì)象
    User user = new User("虎哥", 21);
    // 手動(dòng)序列化
    String json = mapper.writeValueAsString(user);
    // 寫(xiě)入數(shù)據(jù)
    stringRedisTemplate.opsForValue().set("user:200", json);

    // 獲取數(shù)據(jù)
    String jsonUser = stringRedisTemplate.opsForValue().get("user:200");
    // 手動(dòng)反序列化
    User user1 = mapper.readValue(jsonUser, User.class);
    System.out.println("user1 = " + user1);
}

測(cè)試代碼

package com.itheima.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@SpringBootTest
@RunWith(SpringRunner.class)
public class SpringDataRedisTest {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 操作String類型數(shù)據(jù)
     */
    @Test
    public void testString(){
        redisTemplate.opsForValue().set("city123","beijing");

        String value = (String) redisTemplate.opsForValue().get("city123");
        System.out.println(value);

        redisTemplate.opsForValue().set("key1","value1",10l, TimeUnit.SECONDS);

        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("city1234", "nanjing");
        System.out.println(aBoolean);
    }

    /**
     * 操作Hash類型數(shù)據(jù)
     */
    @Test
    public void testHash(){
        HashOperations hashOperations = redisTemplate.opsForHash();

        //存值
        hashOperations.put("002","name","xiaoming");
        hashOperations.put("002","age","20");
        hashOperations.put("002","address","bj");

        //取值
        String age = (String) hashOperations.get("002", "age");
        System.out.println(age);

        //獲得hash結(jié)構(gòu)中的所有字段
        Set keys = hashOperations.keys("002");
        for (Object key : keys) {
            System.out.println(key);
        }

        //獲得hash結(jié)構(gòu)中的所有值
        List values = hashOperations.values("002");
        for (Object value : values) {
            System.out.println(value);
        }
    }

    /**
     * 操作List類型的數(shù)據(jù)
     */
    @Test
    public void testList(){
        ListOperations listOperations = redisTemplate.opsForList();

        //存值
        listOperations.leftPush("mylist","a");
        listOperations.leftPushAll("mylist","b","c","d");

        //取值
        List<String> mylist = listOperations.range("mylist", 0, -1);
        for (String value : mylist) {
            System.out.println(value);
        }

        //獲得列表長(zhǎng)度 llen
        Long size = listOperations.size("mylist");
        int lSize = size.intValue();
        for (int i = 0; i < lSize; i++) {
            //出隊(duì)列
            String element = (String) listOperations.rightPop("mylist");
            System.out.println(element);
        }
    }

    /**
     * 操作Set類型的數(shù)據(jù)
     */
    @Test
    public void testSet(){
        SetOperations setOperations = redisTemplate.opsForSet();

        //存值
        setOperations.add("myset","a","b","c","a");

        //取值
        Set<String> myset = setOperations.members("myset");
        for (String o : myset) {
            System.out.println(o);
        }

        //刪除成員
        setOperations.remove("myset","a","b");

        //取值
        myset = setOperations.members("myset");
        for (String o : myset) {
            System.out.println(o);
        }

    }

    /**
     * 操作ZSet類型的數(shù)據(jù)
     */
    @Test
    public void testZset(){
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();

        //存值
        zSetOperations.add("myZset","a",10.0);
        zSetOperations.add("myZset","b",11.0);
        zSetOperations.add("myZset","c",12.0);
        zSetOperations.add("myZset","a",13.0);

        //取值
        Set<String> myZset = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset) {
            System.out.println(s);
        }

        //修改分?jǐn)?shù)
        zSetOperations.incrementScore("myZset","b",20.0);

        //取值
        myZset = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset) {
            System.out.println(s);
        }

        //刪除成員
        zSetOperations.remove("myZset","a","b");

        //取值
        myZset = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset) {
            System.out.println(s);
        }
    }

    /**
     * 通用操作,針對(duì)不同的數(shù)據(jù)類型都可以操作
     */
    @Test
    public void testCommon(){
        //獲取Redis中所有的key
        Set<String> keys = redisTemplate.keys("*");
        for (String key : keys) {
            System.out.println(key);
        }

        //判斷某個(gè)key是否存在
        Boolean itcast = redisTemplate.hasKey("itcast");
        System.out.println(itcast);

        //刪除指定key
        redisTemplate.delete("myZset");

        //獲取指定key對(duì)應(yīng)的value的數(shù)據(jù)類型
        DataType dataType = redisTemplate.type("myset");
        System.out.println(dataType.name());

    }
}

6.4 Hash結(jié)構(gòu)操作

在基礎(chǔ)篇的最后,咱們對(duì)Hash結(jié)構(gòu)操作一下,收一個(gè)小尾巴,這個(gè)代碼咱們就不再解釋啦

馬上就開(kāi)始新的篇章~~~進(jìn)入到我們的Redis實(shí)戰(zhàn)篇文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-408931.html


@SpringBootTest
class RedisStringTests {

	@Test

	void testHash() {
  		 stringRedisTemplate.opsForHash().put("user:400", "name", "虎哥");
    	stringRedisTemplate.opsForHash().put("user:400", "age", "21");

		Map<Object, Object> entries = 	stringRedisTemplate.opsForHash().entries("user:400");
System.out.println("entries = " + entries);

}

}

到了這里,關(guān)于基于Spring boot和Mybatis外賣(mài)項(xiàng)目瑞吉外賣(mài)Day9-Redis的快速入門(mén)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【SpringBoot項(xiàng)目】SpringBoot項(xiàng)目-瑞吉外賣(mài)【day03】分類管理

    【SpringBoot項(xiàng)目】SpringBoot項(xiàng)目-瑞吉外賣(mài)【day03】分類管理

    ??博客x主頁(yè):己不由心王道長(zhǎng)??! ??文章說(shuō)明:SpringBoot項(xiàng)目-瑞吉外賣(mài)【day03】分類管理?? ?系列專欄:SpringBoot項(xiàng)目 ??本篇內(nèi)容:對(duì)黑馬的瑞吉外賣(mài)項(xiàng)目的day03進(jìn)行筆記和項(xiàng)目實(shí)現(xiàn)?? ??每日一語(yǔ):生活不可能像你想象得那么好,但也不會(huì)像你想象得那么糟。?? ??

    2024年02月22日
    瀏覽(17)
  • 瑞吉外賣(mài)-Day01

    瑞吉外賣(mài)-Day01

    軟件開(kāi)發(fā)整體介紹 瑞吉外賣(mài)項(xiàng)目介紹 開(kāi)發(fā)環(huán)境搭建 后臺(tái)登錄功能開(kāi)發(fā) 后臺(tái)退出功能開(kāi)發(fā) 作為一名軟件開(kāi)發(fā)工程師,我們需要了解在軟件開(kāi)發(fā)過(guò)程中的開(kāi)發(fā)流程, 以及軟件開(kāi)發(fā)過(guò)程中涉及到的崗位角色,角色的分工、職責(zé), 并了解軟件開(kāi)發(fā)中涉及到的三種軟件環(huán)境。那么這

    2024年02月12日
    瀏覽(30)
  • 瑞吉外賣(mài)day4

    瑞吉外賣(mài)day4

    介紹 ?服務(wù)端要接收客戶端頁(yè)面上傳的文件,通常都會(huì)使用Apache的兩個(gè)組件 1.commons-file upload 2.commons-io Spring框架在spring-web包中對(duì)文件上傳進(jìn)行了封裝。只需要在Controller的方法中聲明一個(gè)MultipartFile類型的參數(shù)即可接受上傳的文件 代碼實(shí)現(xiàn) upload方法里的形參名要保證與前端提

    2024年02月04日
    瀏覽(50)
  • 瑞吉外賣(mài)day1

    瑞吉外賣(mài)day1

    本項(xiàng)目(瑞吉外賣(mài))是專門(mén)為餐飲企業(yè)(餐廳、飯店)定制的一款軟件產(chǎn)品,包括系統(tǒng)管理后臺(tái)和移動(dòng)端應(yīng)用兩部分。其中系統(tǒng)管理后臺(tái)主要提供給餐飲企業(yè)內(nèi)部員工使用,可以對(duì)餐廳的菜品、套餐、訂單等進(jìn)行管理維護(hù)。移動(dòng)端應(yīng)用 心 主要提供給消費(fèi)者使用,可以在線瀏

    2024年02月03日
    瀏覽(23)
  • 瑞吉外賣(mài)項(xiàng)目——瑞吉外賣(mài)

    瑞吉外賣(mài)項(xiàng)目——瑞吉外賣(mài)

    需求分析:產(chǎn)品原型、需求規(guī)格說(shuō)明書(shū) 設(shè)計(jì):產(chǎn)品文檔、UI界面設(shè)計(jì)、概要設(shè)計(jì)、詳細(xì)設(shè)計(jì)、數(shù)據(jù)庫(kù)設(shè)計(jì) 編碼:項(xiàng)目代碼、單元測(cè)試 測(cè)試:測(cè)試用例、測(cè)試報(bào)告 上線運(yùn)維:軟件環(huán)境安裝、配置 項(xiàng)目經(jīng)理:對(duì)整個(gè)項(xiàng)目負(fù)責(zé),任務(wù)分配、把控進(jìn)度 產(chǎn)品經(jīng)理:進(jìn)行需求調(diào)研,輸

    2023年04月26日
    瀏覽(22)
  • 瑞吉外賣(mài)項(xiàng)目——前后端分離

    瑞吉外賣(mài)項(xiàng)目——前后端分離

    前后端分離開(kāi)發(fā),就是在項(xiàng)目開(kāi)發(fā)過(guò)程中,對(duì)于前端代碼的開(kāi)發(fā)由專門(mén)的 前端開(kāi)發(fā)人員 負(fù)責(zé),后端代碼則由 后端開(kāi)發(fā)人員 負(fù)責(zé),這樣可以做到分工明確、各司其職,提高開(kāi)發(fā)效率,前后端代碼并行開(kāi)發(fā),可以加快項(xiàng)目開(kāi)發(fā)進(jìn)度。 目前,前后端分離開(kāi)發(fā)方式已經(jīng)被越來(lái)越多

    2023年04月20日
    瀏覽(16)
  • 項(xiàng)目筆記-瑞吉外賣(mài)(全)

    項(xiàng)目筆記-瑞吉外賣(mài)(全)

    1.對(duì)后端返回請(qǐng)求值的分析 2.對(duì)不同種請(qǐng)求參數(shù)的分析 3.事務(wù)管理 1.軟件開(kāi)發(fā)整體介紹 2.項(xiàng)目整體介紹?? 后端:管理菜品和員工信息 前臺(tái):通過(guò)手機(jī)端,可以瀏覽菜品和添加客戶端 開(kāi)發(fā)項(xiàng)目流程: 實(shí)現(xiàn)基本需求,用戶能在手機(jī)瀏覽器訪問(wèn) 對(duì)移動(dòng)端應(yīng)用改進(jìn),使用微信小程

    2024年02月07日
    瀏覽(24)
  • 瑞吉外賣(mài)項(xiàng)目記錄

    瑞吉外賣(mài)項(xiàng)目記錄

    本文為個(gè)人學(xué)習(xí)黑馬《瑞吉外賣(mài)》項(xiàng)目后進(jìn)行的項(xiàng)目總結(jié),更偏向于對(duì)自己編寫(xiě)文本能力的鍛煉以及對(duì)項(xiàng)目知識(shí)點(diǎn)的簡(jiǎn)短記錄。因?yàn)閭€(gè)人能力問(wèn)題,其中可行性分析和測(cè)試部分只進(jìn)行了小標(biāo)題的陳列,并沒(méi)有進(jìn)行編輯。對(duì)《瑞吉外賣(mài)》項(xiàng)目感興趣的朋友也可以瀏覽本文后再去

    2024年02月05日
    瀏覽(19)
  • 瑞吉外賣(mài)項(xiàng)目----(2)緩存優(yōu)化

    瑞吉外賣(mài)項(xiàng)目----(2)緩存優(yōu)化

    將項(xiàng)目推送到遠(yuǎn)程倉(cāng)庫(kù)里,教程在git 提交遠(yuǎn)程倉(cāng)庫(kù)前建議取消代碼檢查 創(chuàng)建新的分支v1.0(用于實(shí)現(xiàn)緩存優(yōu)化)并推送到遠(yuǎn)程倉(cāng)庫(kù) 1.1.1 maven坐標(biāo) 導(dǎo)入spring-data-redis的maven坐標(biāo): 1.1.2 配置文件 在application.yml中加入redis相關(guān)配置: 1.1.3 配置類 在項(xiàng)目中加入RedisConfig 1.2.1 實(shí)現(xiàn)思路

    2024年02月14日
    瀏覽(16)
  • Java項(xiàng)目實(shí)戰(zhàn)筆記(瑞吉外賣(mài))-4

    Java項(xiàng)目實(shí)戰(zhàn)筆記(瑞吉外賣(mài))-4

    問(wèn)題分析 前面已經(jīng)完成了后臺(tái)系統(tǒng)的員工管理功能開(kāi)發(fā),在新增員工時(shí)需要設(shè)置創(chuàng)建時(shí)間、創(chuàng)建人、修改時(shí)間、修改人等字段,在編輯員工時(shí)需要設(shè)置修改時(shí)間和修改人等字段。這些字段屬于公共字段,也就是很多表中都有這些字段,如下: 能不能對(duì)于這些公共字段在某個(gè)

    2023年04月17日
    瀏覽(21)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包