jlzzjlzz亚洲乱熟在线播放

系統城裝機大師 - 唯一官網:www.farandoo.com!

當前位置:首頁 > 數據庫 > Mysql > 詳細頁面

深入理解 Redis Template及4種序列化方式

時間:2021-03-24來源:www.farandoo.com作者:電腦系統城

使用Spring 提供的 Spring Data Redis 操作redis 必然要使用Spring提供的模板類 RedisTemplate, 今天我們好好的看看這個模板類 。

RedisTemplate

在這里插入圖片描述

看看4個序列化相關的屬性 ,主要是 用于 KEY 和 VALUE 的序列化 。 舉個例子,比如說我們經常會將POJO 對象存儲到 Redis 中,一般情況下會使用 JSON 方式序列化成字符串,存儲到 Redis 中 。

Spring提供的Redis數據結構的操作類

  • 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

再看個常用的 StringRedisTemplate

RedisTemplate<K, V> 支持泛型,StringRedisTemplate K V 均為String類型。

org.springframework.data.redis.core.StringRedisTemplate 繼承 RedisTemplate 類,使用 org.springframework.data.redis.serializer.StringRedisSerializer 字符串序列化方式。

在這里插入圖片描述

RedisSerializer 序列化 接口

RedisSerializer接口 是 Redis 序列化接口,用于 Redis KEY 和 VALUE 的序列化

在這里插入圖片描述

RedisSerializer 接口的實現類 如下

在這里插入圖片描述

歸類一下

  • JDK 序列化方式 (默認)
  • String 序列化方式J
  • SON 序列化方式
  • XML 序列化方式

JDK 序列化方式 (默認)

org.springframework.data.redis.serializer.JdkSerializationRedisSerializer ,默認情況下,RedisTemplate 使用該數據列化方式。

我們來看下源碼 RedisTemplate#afterPropertiesSet()

在這里插入圖片描述 

Spring Boot 自動化配置 RedisTemplate Bean 對象時,就未設置默認的序列化方式。

絕大多數情況下,不推薦使用 JdkSerializationRedisSerializer 進行序列化。主要是不方便人工排查數據。

我們來做個測試

在這里插入圖片描述

運行單元測試

在這里插入圖片描述

 

看不懂呀 ,老哥

KEY 前面帶著奇怪的 16 進制字符 , VALUE 也是一串奇怪的 16 進制字符 。。。。。

為什么是這樣一串奇怪的 16 進制? ObjectOutputStream#writeString(String str, boolean unshared) 實際就是標志位 + 字符串長度 + 字符串內容

KEY 被序列化成這樣,線上通過 KEY 去查詢對應的 VALUE非常不方便,所以 KEY 肯定是不能被這樣序列化的。

VALUE 被序列化成這樣,除了閱讀可能困難一點,不支持跨語言外,實際上也沒還OK。不過,實際線上場景,還是使用 JSON 序列化居多。

String 序列化方式

org.springframework.data.redis.serializer.StringRedisSerializer ,字符串和二進制數組的直接轉換

在這里插入圖片描述

絕大多數情況下,我們 KEY 和 VALUE 都會使用這種序列化方案。

JSON 序列化方式

org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer 使用 Jackson 實現 JSON 的序列化方式,并且從 Generic 單詞可以看出,是支持所有類。

1
2
3
4
5
6
7
8
9
10
public GenericJackson2JsonRedisSerializer(@Nullable String classPropertyTypeName) {
 
            .....
            .....
        if (StringUtils.hasText(classPropertyTypeName)) {
            mapper.enableDefaultTypingAsProperty(DefaultTyping.NON_FINAL, classPropertyTypeName);
        } else {
            mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
        }
    }

classPropertyTypeName 不為空的話,使用傳入對象的 classPropertyTypeName 屬性對應的值,作為默認類型(Default Typing) ,否則使用傳入對象的類全名,作為默認類型(Default Typing)。

我們來思考下,在將一個對象序列化成一個字符串,怎么保證字符串反序列化成對象的類型呢?Jackson 通過 Default Typing ,會在字符串多冗余一個類型,這樣反序列化就知道具體的類型了

 

先說個結論

標準JSON

1
2
3
4
5
{
 "id": 100,
 "name": "小工匠",
 "sex": "Male"
}

使用 Jackson Default Typing 機制序列化

1
2
3
4
5
6
{
 "@class": "com.artisan.domain.Artisan",
 "id": 100,
 "name": "小工匠",
 "sex": "Male"
}

示例

測試一把

【配置類】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Bean
public RedisTemplate<String, Object> redisTemplate() {
 // 創建 RedisTemplate 對象
 RedisTemplate<String, Object> template = new RedisTemplate<>();
 
 // 設置 RedisConnection 工廠。 它就是實現多種 Java Redis 客戶端接入的秘密工廠
 template.setConnectionFactory(connectionFactory);
 
 // 使用 String 序列化方式,序列化 KEY 。
 template.setKeySerializer(RedisSerializer.string());
 
 // 使用 JSON 序列化方式(庫是 Jackson ),序列化 VALUE 。
 template.setValueSerializer(RedisSerializer.json());
 
 return template;
}

【單元測試】

1
2
3
4
5
6
7
8
9
@Test
public void testJacksonSerializer() {
 Artisan artisan = new Artisan();
 artisan.setName("小工匠");
 artisan.setId(100);
 artisan.setSex("Male");
 // set
 redisTemplate.opsForValue().set("artisan", artisan);
}

【結果】

在這里插入圖片描述

是不是多了@class 屬性,反序列化的對象的類型就可以從這里獲取到。

@class 屬性看似完美解決了反序列化后的對象類型,但是帶來 JSON 字符串占用變大,所以實際項目中,我們很少采用 Jackson2JsonRedisSerializer

XML 序列化方式

org.springframework.data.redis.serializer.OxmSerializer使用 Spring OXM 實現將對象和 String 的轉換,從而 String 和二進制數組的轉換。 沒見過哪個項目用過,不啰嗦了

分享到:

相關信息

系統教程欄目

欄目熱門教程

人氣教程排行

站長推薦

熱門系統下載