深⼊理解RedisTemplate及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.StringRedisTemplate继承 RedisTemplate 类,使⽤org.dis.serializer.StringRedisSerializer字符串序列化⽅式。
RedisSerializer 序列化接⼝
RedisSerializer接⼝是 Redis 序列化接⼝,⽤于 Redis KEY 和 VALUE 的序列化
redis支持的数据结构RedisSerializer 接⼝的实现类如下
归类⼀下
JDK 序列化⽅式(默认)
String 序列化⽅式J
SON 序列化⽅式
XML 序列化⽅式
JDK 序列化⽅式(默认)
org.dis.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.dis.serializer.StringRedisSerializer,字符串和⼆进制数组的直接转换
绝⼤多数情况下,我们 KEY 和 VALUE 都会使⽤这种序列化⽅案。
JSON 序列化⽅式
org.dis.serializer.GenericJackson2JsonRedisSerializer使⽤ Jackson 实现 JSON 的序列化⽅式,并且从 Generic 单词可以看出,是⽀持所有类。
public GenericJackson2JsonRedisSerializer(@Nullable String classPropertyTypeName) {
.....
.....
if (StringUtils.hasText(classPropertyTypeName)) {
} else {
}
}
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.dis.serializer.OxmSerializer使⽤ Spring OXM 实现将对象和 String 的转换,从⽽ String 和⼆进制数组的转换。没见过哪个项⽬⽤过,不啰嗦了
到此这篇关于深⼊理解 Redis Template及4种序列化⽅式的⽂章就介绍到这了,更多相关Redis Template序列化内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。