Redis的常見命令和客戶端使用
1.初識Redis
Redis是一種鍵值型的NoSql數據庫,這里有兩個關鍵字:
-
鍵值型
-
NoSql
其中鍵值型,是指Redis中存儲的數據都是以key、value對的形式存儲,而value的形式多種多樣,可以是字符串、數值、甚至json:
而NoSql則是相對于傳統關系型數據庫而言,有很大差異的一種數據庫。
1.1.認識NoSQL
NoSql可以翻譯做Not Only Sql(不僅僅是SQL),或者是No Sql(非Sql的)數據庫。是相對于傳統關系型數據庫而言,有很大差異的一種特殊的數據庫,因此也稱之為非關系型數據庫。
1.1.1.結構化與非結構化
傳統關系型數據庫是結構化數據,每一張表都有嚴格的約束信息:字段名、字段數據類型、字段約束等等信息,插入的數據必須遵守這些約束:
而NoSql則對數據庫格式沒有嚴格約束,往往形式松散,自由。
可以是鍵值型:
也可以是文檔型:
甚至可以是圖格式:
1.1.2.關聯和非關聯
傳統數據庫的表與表之間往往存在關聯,例如外鍵:
而非關系型數據庫不存在關聯關系,要維護關系要么靠代碼中的業務邏輯,要么靠數據之間的耦合:
{id: 1,name: "張三",orders: [{id: 1,item: {id: 10, title: "榮耀6", price: 4999}},{id: 2,item: {id: 20, title: "小米11", price: 3999}}]
}
此處要維護“張三”的訂單與商品“榮耀”和“小米11”的關系,不得不冗余的將這兩個商品保存在張三的訂單文檔中,不夠優雅。還是建議用業務來維護關聯關系。
1.1.3.查詢方式
傳統關系型數據庫會基于Sql語句做查詢,語法有統一標準;
而不同的非關系數據庫查詢語法差異極大,五花八門各種各樣。
1.1.4.事務
傳統關系型數據庫能滿足事務ACID的原則。
而非關系型數據庫往往不支持事務,或者不能嚴格保證ACID的特性,只能實現基本的一致性。
1.1.5.總結
除了上述四點以外,在存儲方式、擴展性、查詢性能上關系型與非關系型也都有著顯著差異,總結如下:
-
存儲方式
-
關系型數據庫基于磁盤進行存儲,會有大量的磁盤IO,對性能有一定影響
-
非關系型數據庫,他們的操作更多的是依賴于內存來操作,內存的讀寫速度會非常快,性能自然會好一些
-
-
擴展性
-
關系型數據庫集群模式一般是主從,主從數據一致,起到數據備份的作用,稱為垂直擴展。
-
非關系型數據庫可以將數據拆分,存儲在不同機器上,可以保存海量數據,解決內存大小有限的問題。稱為水平擴展。
-
關系型數據庫因為表之間存在關聯關系,如果做水平擴展會給數據查詢帶來很多麻煩
-
1.2.認識Redis
Redis誕生于2009年全稱是Remote Dictionary Server 遠程詞典服務器,是一個基于內存的鍵值型NoSQL數據庫。
特征:
-
鍵值(key-value)型,value支持多種不同數據結構,功能豐富
-
單線程,每個命令具備原子性
-
低延遲,速度快(基于內存、IO多路復用、良好的編碼)。
-
支持數據持久化
-
支持主從集群、分片集群
-
支持多語言客戶端
作者:Antirez
Redis的官方網站地址:Redis - The Real-time Data Platform
1.3.安裝Redis
大多數企業都是基于Linux服務器來部署項目,而且Redis官方也沒有提供Windows版本的安裝包。因此課程中我們會基于Linux系統來安裝Redis.
此處選擇的Linux版本為CentOS 7.
可以在windwos安裝,參考:
Redis下載、安裝(簡單高效,一分鐘完成!!!!!)_redis 下載-CSDN博客
1.3.1.依賴庫
Redis是基于C語言編寫的,因此首先需要安裝Redis所需要的gcc依賴:
yum install -y gcc tcl
1.3.2.上傳安裝包并解壓
然后將課前資料提供的Redis安裝包上傳到虛擬機的任意目錄:
例如,我放到了/usr/local/src 目錄:
解壓縮:
tar -xzf redis-6.2.6.tar.gz
解壓后:
進入redis目錄:
cd redis-6.2.6
運行編譯命令:
make && make install
如果沒有出錯,應該就安裝成功了。
默認的安裝路徑是在 /usr/local/bin
目錄下:
該目錄已經默認配置到環境變量,因此可以在任意目錄下運行這些命令。其中:
-
redis-cli:是redis提供的命令行客戶端
-
redis-server:是redis的服務端啟動腳本
-
redis-sentinel:是redis的哨兵啟動腳本
1.3.3.啟動
redis的啟動方式有很多種,例如:
-
默認啟動
-
指定配置啟動
-
開機自啟
1.3.4.默認啟動
安裝完成后,在任意目錄輸入redis-server命令即可啟動Redis:
redis-server
如圖:
這種啟動屬于前臺啟動
,會阻塞整個會話窗口,窗口關閉或者按下CTRL + C
則Redis停止。不推薦使用。
1.3.5.指定配置啟動
如果要讓Redis以后臺
方式啟動,則必須修改Redis配置文件,就在我們之前解壓的redis安裝包下(/usr/local/src/redis-6.2.6
),名字叫redis.conf:
我們先將這個配置文件備份一份:
cp redis.conf redis.conf.bck
然后修改redis.conf文件中的一些配置:
# 允許訪問的地址,默認是127.0.0.1,會導致只能在本地訪問。修改為0.0.0.0則可以在任意IP訪問,生產環境不要設置為0.0.0.0 bind 0.0.0.0 # 守護進程,修改為yes后即可后臺運行 daemonize yes # 密碼,設置后訪問Redis必須輸入密碼 requirepass 123321
Redis的其它常見配置:
# 監聽的端口 port 6379 # 工作目錄,默認是當前目錄,也就是運行redis-server時的命令,日志、持久化等文件會保存在這個目錄 dir . # 數據庫數量,設置為1,代表只使用1個庫,默認有16個庫,編號0~15 databases 1 # 設置redis能夠使用的最大內存 maxmemory 512mb # 日志文件,默認為空,不記錄日志,可以指定日志文件名 logfile "redis.log"
啟動Redis:
# 進入redis安裝目錄 cd /usr/local/src/redis-6.2.6 # 啟動 redis-server redis.conf
停止服務:
# 利用redis-cli來執行 shutdown 命令,即可停止 Redis 服務, # 因為之前配置了密碼,因此需要通過 -u 來指定密碼 redis-cli -u 123321 shutdown
1.3.6.開機自啟
我們也可以通過配置來實現開機自啟。
首先,新建一個系統服務文件:
vi /etc/systemd/system/redis.service
內容如下:
[Unit] Description=redis-server After=network.target ? [Service] Type=forking ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf PrivateTmp=true ? [Install] WantedBy=multi-user.target
然后重載系統服務:
systemctl daemon-reload
現在,我們可以用下面這組命令來操作redis了:
# 啟動 systemctl start redis # 停止 systemctl stop redis # 重啟 systemctl restart redis # 查看狀態 systemctl status redis
執行下面的命令,可以讓redis開機自啟:
systemctl enable redis
1.4.Redis桌面客戶端
安裝完成Redis,我們就可以操作Redis,實現數據的CRUD了。這需要用到Redis客戶端,包括:
-
命令行客戶端
-
圖形化桌面客戶端
-
編程客戶端
1.4.1.Redis命令行客戶端
Redis安裝完成后就自帶了命令行客戶端:redis-cli,使用方式如下:
redis-cli [options] [commonds]
其中常見的options有:
-
-h 127.0.0.1
:指定要連接的redis節點的IP地址,默認是127.0.0.1 -
-p 6379
:指定要連接的redis節點的端口,默認是6379 -
-a 123321
:指定redis的訪問密碼
其中的commonds就是Redis的操作命令,例如:
-
ping
:與redis服務端做心跳測試,服務端正常會返回pong
不指定commond時,會進入redis-cli
的交互控制臺:
1.4.2.圖形化桌面客戶端
GitHub上的大神編寫了Redis的圖形化桌面客戶端,地址:https://github.com/uglide/RedisDesktopManager
不過該倉庫提供的是RedisDesktopManager的源碼,并未提供windows安裝包。
在下面這個倉庫可以找到安裝包:https://github.com/lework/RedisDesktopManager-Windows/releases
1.4.3.安裝
在課前資料中可以找到Redis的圖形化桌面客戶端:
解壓縮后,運行安裝程序即可安裝:
安裝完成后,在安裝目錄下找到rdm.exe文件:
雙擊即可運行:
1.4.4.建立連接
點擊左上角的連接到Redis服務器
按鈕:
在彈出的窗口中填寫Redis服務信息:
點擊確定后,在左側菜單會出現這個鏈接:
點擊即可建立連接了。
Redis默認有16個倉庫,編號從0至15. 通過配置文件可以設置倉庫數量,但是不超過16,并且不能自定義倉庫名稱。
如果是基于redis-cli連接Redis服務,可以通過select命令來選擇數據庫:
# 選擇 0號庫 select 0
2.Redis常見命令
Redis是典型的key-value數據庫,key一般是字符串,而value包含很多不同的數據類型:
Redis為了方便我們學習,將操作不同數據類型的命令也做了分組,在官網( https://redis.io/commands?)可以查看到不同的命令:
不同類型的命令稱為一個group,我們也可以通過help命令來查看各種不同group的命令:
接下來,我們就學習常見的五種基本數據類型的相關命令。
2.1.Redis通用命令
通用指令是部分數據類型的,都可以使用的指令,常見的有:
-
KEYS:查看符合模板的所有key
-
DEL:刪除一個指定的key
-
EXISTS:判斷key是否存在
-
EXPIRE:給一個key設置有效期,有效期到期時該key會被自動刪除
-
TTL:查看一個KEY的剩余有效期
通過help [command] 可以查看一個命令的具體用法,例如:
# 查看keys命令的幫助信息: 127.0.0.1:6379> help keys ? KEYS pattern summary: Find all keys matching the given pattern since: 1.0.0 group: generic
2.2.String類型
String類型,也就是字符串類型,是Redis中最簡單的存儲類型。
其value是字符串,不過根據字符串的格式不同,又可以分為3類:
-
string:普通字符串
-
int:整數類型,可以做自增、自減操作
-
float:浮點類型,可以做自增、自減操作
不管是哪種格式,底層都是字節數組形式存儲,只不過是編碼方式不同。字符串類型的最大空間不能超過512m.
2.2.1.String的常見命令
String的常見命令有:
-
SET:添加或者修改已經存在的一個String類型的鍵值對
-
GET:根據key獲取String類型的value
-
MSET:批量添加多個String類型的鍵值對
-
MGET:根據多個key獲取多個String類型的value
-
INCR:讓一個整型的key自增1
-
INCRBY:讓一個整型的key自增并指定步長,例如:incrby num 2 讓num值自增2
-
INCRBYFLOAT:讓一個浮點類型的數字自增并指定步長
-
SETNX:添加一個String類型的鍵值對,前提是這個key不存在,否則不執行
-
SETEX:添加一個String類型的鍵值對,并且指定有效期
2.2.2.Key結構
Redis沒有類似MySQL中的Table的概念,我們該如何區分不同類型的key呢?
例如,需要存儲用戶、商品信息到redis,有一個用戶id是1,有一個商品id恰好也是1,此時如果使用id作為key,那就會沖突了,該怎么辦?
我們可以通過給key添加前綴加以區分,不過這個前綴不是隨便加的,有一定的規范:
Redis的key允許有多個單詞形成層級結構,多個單詞之間用':'隔開,格式如下:
項目名:業務名:類型:id
這個格式并非固定,也可以根據自己的需求來刪除或添加詞條。這樣以來,我們就可以把不同類型的數據區分開了。從而避免了key的沖突問題。
例如我們的項目名稱叫 heima,有user和product兩種不同類型的數據,我們可以這樣定義key:
-
user相關的key:heima:user:1
-
product相關的key:heima:product:1
如果Value是一個Java對象,例如一個User對象,則可以將對象序列化為JSON字符串后存儲:
KEY | VALUE |
---|---|
heima:user:1 | {"id":1, "name": "Jack", "age": 21} |
heima:product:1 | {"id":1, "name": "小米11", "price": 4999} |
并且,在Redis的桌面客戶端中,還會以相同前綴作為層級結構,讓數據看起來層次分明,關系清晰:
2.3.Hash類型
Hash類型,也叫散列,其value是一個無序字典,類似于Java中的HashMap結構。
String結構是將對象序列化為JSON字符串后存儲,當需要修改對象某個字段時很不方便:
Hash結構可以將對象中的每個字段獨立存儲,可以針對單個字段做CRUD:
Hash的常見命令有:
-
HSET key field value:添加或者修改hash類型key的field的值
-
HGET key field:獲取一個hash類型key的field的值
-
HMSET:批量添加多個hash類型key的field的值
-
HMGET:批量獲取多個hash類型key的field的值
-
HGETALL:獲取一個hash類型的key中的所有的field和value
-
HKEYS:獲取一個hash類型的key中的所有的field
-
HINCRBY:讓一個hash類型key的字段值自增并指定步長
-
HSETNX:添加一個hash類型的key的field值,前提是這個field不存在,否則不執行
2.4.List類型
Redis中的List類型與Java中的LinkedList類似,可以看做是一個雙向鏈表結構。既可以支持正向檢索和也可以支持反向檢索。
特征也與LinkedList類似:
-
有序
-
元素可以重復
-
插入和刪除快
-
查詢速度一般
常用來存儲一個有序數據,例如:朋友圈點贊列表,評論列表等。
List的常見命令有:
-
LPUSH key element ... :向列表左側插入一個或多個元素
-
LPOP key:移除并返回列表左側的第一個元素,沒有則返回nil
-
RPUSH key element ... :向列表右側插入一個或多個元素
-
RPOP key:移除并返回列表右側的第一個元素
-
LRANGE key star end:返回一段角標范圍內的所有元素
-
BLPOP和BRPOP:與LPOP和RPOP類似,只不過在沒有元素時等待指定時間,而不是直接返回nil
2.5.Set類型
Redis的Set結構與Java中的HashSet類似,可以看做是一個value為null的HashMap。因為也是一個hash表,因此具備與HashSet類似的特征:
-
無序
-
元素不可重復
-
查找快
-
支持交集、并集、差集等功能
Set的常見命令有:
-
SADD key member ... :向set中添加一個或多個元素
-
SREM key member ... : 移除set中的指定元素
-
SCARD key: 返回set中元素的個數
-
SISMEMBER key member:判斷一個元素是否存在于set中
-
SMEMBERS:獲取set中的所有元素
-
SINTER key1 key2 ... :求key1與key2的交集
例如兩個集合:s1和s2:
求交集:SINTER s1 s2
求s1與s2的不同:SDIFF s1 s2
練習:
-
將下列數據用Redis的Set集合來存儲:
-
張三的好友有:李四、王五、趙六
-
李四的好友有:王五、麻子、二狗
-
利用Set的命令實現下列功能:
-
計算張三的好友有幾人
-
計算張三和李四有哪些共同好友
-
查詢哪些人是張三的好友卻不是李四的好友
-
查詢張三和李四的好友總共有哪些人
-
判斷李四是否是張三的好友
-
判斷張三是否是李四的好友
-
將李四從張三的好友列表中移除
2.6.SortedSet類型
Redis的SortedSet是一個可排序的set集合,與Java中的TreeSet有些類似,但底層數據結構卻差別很大。SortedSet中的每一個元素都帶有一個score屬性,可以基于score屬性對元素排序,底層的實現是一個跳表(SkipList)加 hash表。
SortedSet具備下列特性:
-
可排序
-
元素不重復
-
查詢速度快
因為SortedSet的可排序特性,經常被用來實現排行榜這樣的功能。
SortedSet的常見命令有:
-
ZADD key score member:添加一個或多個元素到sorted set ,如果已經存在則更新其score值
-
ZREM key member:刪除sorted set中的一個指定元素
-
ZSCORE key member : 獲取sorted set中的指定元素的score值
-
ZRANK key member:獲取sorted set 中的指定元素的排名
-
ZCARD key:獲取sorted set中的元素個數
-
ZCOUNT key min max:統計score值在給定范圍內的所有元素的個數
-
ZINCRBY key increment member:讓sorted set中的指定元素自增,步長為指定的increment值
-
ZRANGE key min max:按照score排序后,獲取指定排名范圍內的元素
-
ZRANGEBYSCORE key min max:按照score排序后,獲取指定score范圍內的元素
-
ZDIFF、ZINTER、ZUNION:求差集、交集、并集
注意:所有的排名默認都是升序,如果要降序則在命令的Z后面添加REV即可,例如:
-
升序獲取sorted set 中的指定元素的排名:ZRANK key member
-
降序獲取sorted set 中的指定元素的排名:ZREVRANK key memeber
練習題:
將班級的下列學生得分存入Redis的SortedSet中:
Jack 85, Lucy 89, Rose 82, Tom 95, Jerry 78, Amy 92, Miles 76
并實現下列功能:
-
刪除Tom同學
-
獲取Amy同學的分數
-
獲取Rose同學的排名
-
查詢80分以下有幾個學生
-
給Amy同學加2分
-
查出成績前3名的同學
-
查出成績80分以下的所有同學
3.Redis的Java客戶端
在Redis官網中提供了各種語言的客戶端,地址:https://redis.io/docs/latest/develop/clients/
其中Java客戶端也包含很多:
標記為*的就是推薦使用的java客戶端,包括:
-
Jedis和Lettuce:這兩個主要是提供了Redis命令對應的API,方便我們操作Redis,而SpringDataRedis又對這兩種做了抽象和封裝,因此我們后期會直接以SpringDataRedis來學習。
-
Redisson:是在Redis基礎上實現了分布式的可伸縮的java數據結構,例如Map、Queue等,而且支持跨進程的同步機制:Lock、Semaphore等待,比較適合用來實現特殊的功能需求。
3.1.Jedis客戶端
Jedis的官網地址: https://github.com/redis/jedis
3.1.1.快速入門
我們先來個快速入門:
1)引入依賴:
<!--jedis-->
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.7.0</version>
</dependency>
<!--單元測試-->
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.7.0</version><scope>test</scope>
</dependency>
2)建立連接
新建一個單元測試類,內容如下:
private Jedis jedis;@BeforeEach
void setUp() {// 1.建立連接// jedis = new Jedis("192.168.150.101", 6379);jedis = JedisConnectionFactory.getJedis();// 2.設置密碼jedis.auth("123321");// 3.選擇庫jedis.select(0);
}
3)測試:
@Test
void testString() {// 存入數據String result = jedis.set("name", "虎哥");System.out.println("result = " + result);// 獲取數據String name = jedis.get("name");System.out.println("name = " + name);
}@Test
void testHash() {// 插入hash數據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();}
}
3.1.2.連接池
Jedis本身是線程不安全的,并且頻繁的創建和銷毀連接會有性能損耗,因此我們推薦大家使用Jedis連接池代替Jedis的直連方式。
package com.heima.jedis.util;import redis.clients.jedis.*;public class JedisConnectionFactory {private static JedisPool jedisPool;static {// 配置連接池JedisPoolConfig poolConfig = new JedisPoolConfig();poolConfig.setMaxTotal(8);poolConfig.setMaxIdle(8);poolConfig.setMinIdle(0);poolConfig.setMaxWaitMillis(1000);// 創建連接池對象,參數:連接池配置、服務端ip、服務端端口、超時時間、密碼jedisPool = new JedisPool(poolConfig, "192.168.150.101", 6379, 1000, "123321");}public static Jedis getJedis(){return jedisPool.getResource();}
}
3.2.SpringDataRedis客戶端
SpringData是Spring中數據操作的模塊,包含對各種數據庫的集成,其中對Redis的集成模塊就叫做SpringDataRedis,官網地址:Spring Data Redis
-
提供了對不同Redis客戶端的整合(Lettuce和Jedis)
-
提供了RedisTemplate統一API來操作Redis
-
支持Redis的發布訂閱模型
-
支持Redis哨兵和Redis集群
-
支持基于Lettuce的響應式編程
-
支持基于JDK、JSON、字符串、Spring對象的數據序列化及反序列化
-
支持基于Redis的JDKCollection實現
SpringDataRedis中提供了RedisTemplate工具類,其中封裝了各種對Redis的操作。并且將不同數據類型的操作API封裝到了不同的類型中:
3.2.1.快速入門
SpringBoot已經提供了對SpringDataRedis的支持,使用非常簡單。
首先,新建一個maven項目,然后按照下面步驟執行:
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>
2)配置Redis
spring:redis:host: 192.168.150.101port: 6379password: 123321lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: 100ms
3)注入RedisTemplate
因為有了SpringBoot的自動裝配,我們可以拿來就用:
@SpringBootTest
class RedisStringTests {@Autowiredprivate RedisTemplate redisTemplate;
}
4)編寫測試
@SpringBootTest
class RedisStringTests {@Autowiredprivate RedisTemplate edisTemplate;@Testvoid testString() {// 寫入一條String數據redisTemplate.opsForValue().set("name", "虎哥");// 獲取string數據Object name = stringRedisTemplate.opsForValue().get("name");System.out.println("name = " + name);}
}
3.2.2.自定義序列化
RedisTemplate可以接收任意Object作為值寫入Redis:
只不過寫入前會把Object序列化為字節形式,默認是采用JDK序列化,得到的結果是這樣的:
缺點:
-
可讀性差
-
內存占用較大
我們可以自定義RedisTemplate的序列化方式,代碼如下:
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){// 創建RedisTemplate對象RedisTemplate<String, Object> template = new RedisTemplate<>();// 設置連接工廠template.setConnectionFactory(connectionFactory);// 創建JSON序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();// 設置Key的序列化template.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());// 設置Value的序列化template.setValueSerializer(jsonRedisSerializer);template.setHashValueSerializer(jsonRedisSerializer);// 返回return template;}
}
這里采用了JSON序列化來代替默認的JDK序列化方式。最終結果如圖:
整體可讀性有了很大提升,并且能將Java對象自動的序列化為JSON字符串,并且查詢時能自動把JSON反序列化為Java對象。不過,其中記錄了序列化時對應的class名稱,目的是為了查詢時實現自動反序列化。這會帶來額外的內存開銷。
3.2.3.StringRedisTemplate
為了節省內存空間,我們可以不使用JSON序列化器來處理value,而是統一使用String序列化器,要求只能存儲String類型的key和value。當需要存儲Java對象時,手動完成對象的序列化和反序列化。
因為存入和讀取時的序列化及反序列化都是我們自己實現的,SpringDataRedis就不會將class信息寫入Redis了。
這種用法比較普遍,因此SpringDataRedis就提供了RedisTemplate的子類:StringRedisTemplate,它的key和value的序列化方式默認就是String方式。
省去了我們自定義RedisTemplate的序列化方式的步驟,而是直接使用:
@Autowired
private StringRedisTemplate stringRedisTemplate;
// JSON序列化工具
private static final ObjectMapper mapper = new ObjectMapper();@Test
void testSaveUser() throws JsonProcessingException {// 創建對象User user = new User("虎哥", 21);// 手動序列化String json = mapper.writeValueAsString(user);// 寫入數據stringRedisTemplate.opsForValue().set("user:200", json);// 獲取數據String jsonUser = stringRedisTemplate.opsForValue().get("user:200");// 手動反序列化User user1 = mapper.readValue(jsonUser, User.class);System.out.println("user1 = " + user1);
}