概述
使用Spring 提供的 Spring Data Redis 操作redis 必然要使用Spring提供的模板類 RedisTemplate, 今天我們好好的看看這個(gè)模板類 。
RedisTemplate
![](/d/20211018/1bbc83f6a011bbe6f2fcbc12b04b1039.gif)
看看4個(gè)序列化相關(guān)的屬性 ,主要是 用于 KEY 和 VALUE 的序列化 。 舉個(gè)例子,比如說(shuō)我們經(jīng)常會(huì)將POJO 對(duì)象存儲(chǔ)到 Redis 中,一般情況下會(huì)使用 JSON 方式序列化成字符串,存儲(chǔ)到 Redis 中 。
Spring提供的Redis數(shù)據(jù)結(jié)構(gòu)的操作類
- ValueOperations 類,提供 Redis String API 操作
- ListOperations 類,提供 Redis List API 操作
- SetOperations 類,提供 Redis Set API 操作
- ZSetOperations 類,提供 Redis ZSet(Sorted Set) API 操作
- GeoOperations 類,提供 Redis Geo API 操作
- HyperLogLogOperations 類,提供 Redis HyperLogLog API 操作
StringRedisTemplate
再看個(gè)常用的 StringRedisTemplate
RedisTemplateK, V> 支持泛型,StringRedisTemplate K V 均為String類型。
org.springframework.data.redis.core.StringRedisTemplate
繼承 RedisTemplate 類,使用 org.springframework.data.redis.serializer.StringRedisSerializer
字符串序列化方式。
![](/d/20211018/f5ccaa30b5f3b72f422d3e44b7313e83.gif)
RedisSerializer 序列化 接口
RedisSerializer接口 是 Redis 序列化接口,用于 Redis KEY 和 VALUE 的序列化
![](/d/20211018/84e7d332df06bf97fa1904035a4738ca.gif)
RedisSerializer 接口的實(shí)現(xiàn)類 如下
![](/d/20211018/318c069ead6bbd4a53bdacce4c345356.gif)
歸類一下
- JDK 序列化方式 (默認(rèn))
- String 序列化方式J
- SON 序列化方式
- XML 序列化方式
JDK 序列化方式 (默認(rèn))
org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
,默認(rèn)情況下,RedisTemplate 使用該數(shù)據(jù)列化方式。
我們來(lái)看下源碼 RedisTemplate#afterPropertiesSet()
Spring Boot 自動(dòng)化配置 RedisTemplate Bean 對(duì)象時(shí),就未設(shè)置默認(rèn)的序列化方式。
絕大多數(shù)情況下,不推薦使用 JdkSerializationRedisSerializer 進(jìn)行序列化。主要是不方便人工排查數(shù)據(jù)。
我們來(lái)做個(gè)測(cè)試
![](/d/20211018/34401624ba46035128d640bbcb73c767.gif)
運(yùn)行單元測(cè)試
![](/d/20211018/e85af219ee83825f4b1b09ea51d52da6.gif)
![](/d/20211018/f4ca6434c42b2fad2448e15a0be7bab2.gif)
看不懂呀 ,老哥
KEY 前面帶著奇怪的 16 進(jìn)制字符 , VALUE 也是一串奇怪的 16 進(jìn)制字符 。。。。。
為什么是這樣一串奇怪的 16 進(jìn)制? ObjectOutputStream#writeString(String str, boolean unshared) 實(shí)際就是標(biāo)志位 + 字符串長(zhǎng)度 + 字符串內(nèi)容
KEY 被序列化成這樣,線上通過(guò) KEY 去查詢對(duì)應(yīng)的 VALUE非常不方便,所以 KEY 肯定是不能被這樣序列化的。
VALUE 被序列化成這樣,除了閱讀可能困難一點(diǎn),不支持跨語(yǔ)言外,實(shí)際上也沒(méi)還OK。不過(guò),實(shí)際線上場(chǎng)景,還是使用 JSON 序列化居多。
String 序列化方式
org.springframework.data.redis.serializer.StringRedisSerializer
,字符串和二進(jìn)制數(shù)組的直接轉(zhuǎn)換
![](/d/20211018/285b6ab5430bff95daa222dce7385c3d.gif)
絕大多數(shù)情況下,我們 KEY 和 VALUE 都會(huì)使用這種序列化方案。
JSON 序列化方式
org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer
使用 Jackson 實(shí)現(xiàn) JSON 的序列化方式,并且從 Generic 單詞可以看出,是支持所有類。
public GenericJackson2JsonRedisSerializer(@Nullable String classPropertyTypeName) {
.....
.....
if (StringUtils.hasText(classPropertyTypeName)) {
mapper.enableDefaultTypingAsProperty(DefaultTyping.NON_FINAL, classPropertyTypeName);
} else {
mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
}
}
classPropertyTypeName 不為空的話,使用傳入對(duì)象的 classPropertyTypeName 屬性對(duì)應(yīng)的值,作為默認(rèn)類型(Default Typing) ,否則使用傳入對(duì)象的類全名,作為默認(rèn)類型(Default Typing)。
我們來(lái)思考下,在將一個(gè)對(duì)象序列化成一個(gè)字符串,怎么保證字符串反序列化成對(duì)象的類型呢?Jackson 通過(guò) Default Typing ,會(huì)在字符串多冗余一個(gè)類型,這樣反序列化就知道具體的類型了
![](/d/20211018/c7fcd4a9451ad6a92d98dac5ffd97bcf.gif)
先說(shuō)個(gè)結(jié)論
標(biāo)準(zhǔn)JSON
{
"id": 100,
"name": "小工匠",
"sex": "Male"
}
使用 Jackson Default Typing 機(jī)制序列化
{
"@class": "com.artisan.domain.Artisan",
"id": 100,
"name": "小工匠",
"sex": "Male"
}
示例
測(cè)試一把
【配置類】
@Bean
public RedisTemplateString, Object> redisTemplate() {
// 創(chuàng)建 RedisTemplate 對(duì)象
RedisTemplateString, Object> template = new RedisTemplate>();
// 設(shè)置 RedisConnection 工廠。 它就是實(shí)現(xiàn)多種 Java Redis 客戶端接入的秘密工廠
template.setConnectionFactory(connectionFactory);
// 使用 String 序列化方式,序列化 KEY 。
template.setKeySerializer(RedisSerializer.string());
// 使用 JSON 序列化方式(庫(kù)是 Jackson ),序列化 VALUE 。
template.setValueSerializer(RedisSerializer.json());
return template;
}
【單元測(cè)試】
@Test
public void testJacksonSerializer() {
Artisan artisan = new Artisan();
artisan.setName("小工匠");
artisan.setId(100);
artisan.setSex("Male");
// set
redisTemplate.opsForValue().set("artisan", artisan);
}
【結(jié)果】
![](/d/20211018/8f4e86a2baeaeab0fa299f6fa566815e.gif)
是不是多了@class 屬性,反序列化的對(duì)象的類型就可以從這里獲取到。
@class 屬性看似完美解決了反序列化后的對(duì)象類型,但是帶來(lái) JSON 字符串占用變大,所以實(shí)際項(xiàng)目中,我們很少采用 Jackson2JsonRedisSerializer
XML 序列化方式
org.springframework.data.redis.serializer.OxmSerializer
使用 Spring OXM 實(shí)現(xiàn)將對(duì)象和 String 的轉(zhuǎn)換,從而 String 和二進(jìn)制數(shù)組的轉(zhuǎn)換。 沒(méi)見(jiàn)過(guò)哪個(gè)項(xiàng)目用過(guò),不啰嗦了
到此這篇關(guān)于深入理解 Redis Template及4種序列化方式的文章就介紹到這了,更多相關(guān)Redis Template序列化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Spring學(xué)習(xí)筆記之RedisTemplate的配置與使用教程
- 在Java中使用redisTemplate操作緩存的方法示例
- spring boot整合redis實(shí)現(xiàn)RedisTemplate三分鐘快速入門
- RedisTemplate中opsForValue和opsForList方法的使用詳解