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

 更新时间:2021年03月24日 14:20:11   作者:小小工匠  
这篇文章主要介绍了深入理解 Redis Template及4种序列化方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

概述

使用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 单词可以看出,是支持所有类。

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

{
 "id": 100,
 "name": "小工匠",
 "sex": "Male"
}

使用 Jackson Default Typing 机制序列化

{
 "@class": "com.artisan.domain.Artisan",
 "id": 100,
 "name": "小工匠",
 "sex": "Male"
}

示例

测试一把

【配置类】

 @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;
 }

【单元测试】

 @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 和二进制数组的转换。 没见过哪个项目用过,不啰嗦了

到此这篇关于深入理解 Redis Template及4种序列化方式的文章就介绍到这了,更多相关Redis Template序列化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解redis分布式锁(优化redis分布式锁的过程及Redisson使用)

    详解redis分布式锁(优化redis分布式锁的过程及Redisson使用)

    在分布式的开发中,以电商库存的更新功能进行讲解,在实际的应用中相同功能的消费者是有多个的,这篇文章主要介绍了redis分布式锁详解(优化redis分布式锁的过程及Redisson使用),需要的朋友可以参考下
    2021-11-11
  • Redis三种特殊数据类型的具体使用

    Redis三种特殊数据类型的具体使用

    本文主要介绍了Redis三种特殊数据类型的具体使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • redis中使用java脚本实现分布式锁

    redis中使用java脚本实现分布式锁

    这篇文章主要介绍了redis中使用java脚本实现分布式锁,本文同时讲解了java脚本和lua脚本实现分布式锁,需要的朋友可以参考下
    2015-01-01
  • Redis源码环境构建过程详解

    Redis源码环境构建过程详解

    这篇文章主要介绍了Redis源码环境构建过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • Redis如何清理过期的key以及对应的解决方法分析

    Redis如何清理过期的key以及对应的解决方法分析

    这篇文章主要介绍了Redis如何清理过期的key以及对应的解决方法的相关资料,Redis提供了多种过期删除策略和内存淘汰策略,以管理缓存和临时数据,需要的朋友可以参考下
    2025-03-03
  • redis lua限流算法实现示例

    redis lua限流算法实现示例

    这篇文章主要为大家介绍了redis lua限流算法实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Redis中Scan命令的基本使用教程

    Redis中Scan命令的基本使用教程

    这篇文章主要给大家介绍了关于Redis中Scan命令的基本使用教程,文中通过示例代码介绍的非常详细,对大家学习或者使用Redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • Redis实现布隆过滤器的方法及原理

    Redis实现布隆过滤器的方法及原理

    布隆过滤器优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。本文将介绍布隆过滤器的原理以及Redis如何实现布隆过滤器,感兴趣的朋友跟随小编一起看看吧
    2019-12-12
  • Redis是单线程的吗

    Redis是单线程的吗

    Redis使用单线程的原因就是多线程并不能有效提升Redis的性能,相反可能还会降低性能,所以自然而然使用单线程,本文给大家详细介绍了Redis为什么是单线程的,感兴趣的朋友跟随小编一起看看吧
    2023-06-06
  • 面试常问:如何保证Redis缓存和数据库的数据一致性

    面试常问:如何保证Redis缓存和数据库的数据一致性

    在实际开发过程中,缓存的使用频率是非常高的,只要使用缓存和数据库存储,就难免会出现双写时数据一致性的问题,那我们又该如何解决呢
    2021-09-09

最新评论