Redis的序列化

时间:2025-03-10 21:18:42

序列化方式概述

对比同份数据初次序列化时的情况(很多帖子都没有考虑序列化的同份数据是否为二次加载的情况,就给出了结论)

  1. StringRedisSerializer: 简单的字符串序列化,可视化性好(内部就是通过String类的new String(bytes) & ()实现的序列化)
  2. JdkSerializationRedisSerializer: Java提供的序列化方式,效率高,占用空间少,可视化性差
  3. Jackson2JsonRedisSerializer: 序列化为json字符串,效率低于JdkSerializationRedisSerializer,占用空间多,可视化性好,默认情况下对泛型支持差
  4. GenericJackson2JsonRedisSerializer: 序列化为json字符串,效率同Jackson2JsonRedisSerializer,占用空间多,可视化性好,默认情况下对泛型支持友好

Jackson2JsonRedisSerializer 对比 GenericJackson2JsonRedisSerializer

Jackson2JsonRedisSerializer

[
    {
        "id": "1",
        "parentId": "2",
        "content": "Node1",
        "children": null
    },
    {
        "id": null,
        "parentId": null,
        "content": null,
        "children": null
    }
]

GenericJackson2JsonRedisSerializer

[
    "",
    [
        {
            "@class": "",
            "id": "1",
            "parentId": "2",
            "content": "Node1",
            "children": null
        },
        {
            "@class": "",
            "id": null,
            "parentId": null,
            "content": null,
            "children": null
        }
    ]
]

上面分别是两种序列化方式的结果,

GenericJackson2JsonRedisSerializer根据额外插入的类全限定名通过反射可以正确得到实体类的实例。

而Jackson2JsonRedisSerializer由于没有插入额外的信息,那么只能通过不同的数据结构来组装反序列化后的内容。例如上面的Json串反序列化的结果类型为: ArrayList<LinkedHashMap>,使用LinkedHashMap来组装实体类对象的字段与字段值。

为什么会这样?

二者本质都是使用的ObjectMapper,只不过GenericJackson2JsonRedisSerializer在内部对ObjectMapper进行了特定配置而已:

public GenericJackson2JsonRedisSerializer() {
    this((String) null);
}

public GenericJackson2JsonRedisSerializer(@Nullable String classPropertyTypeName) {

    this(new ObjectMapper());

    registerNullValueSerializer(mapper, classPropertyTypeName);

    // 下面的配置就是在序列化结果中加入实体类全限定名的配置 
    if ((classPropertyTypeName)) {
        (DefaultTyping.NON_FINAL, classPropertyTypeName);
    } else {
        (DefaultTyping.NON_FINAL, );
    }
}

public GenericJackson2JsonRedisSerializer(ObjectMapper mapper) {
    (mapper, "ObjectMapper must not be null!");
     = mapper;
}

使用Jackson2JsonRedisSerializer时,可以自己创建一个ObjectMapper对象,并进行上面的配置后,通过构造方法进行传递。那么最后Jackson2JsonRedisSerializer的序列化效果和GenericJackson2JsonRedisSerializer是一样的。

常用配置

根据以上内容,给出一份RedisTemplate的常用配置:

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

    // key   采用StringRedisSerializer
    // value 采用GenericJackson2JsonRedisSerializer

    RedisTemplate<String, Object> template = new RedisTemplate<>();
    // 关闭启用默认配置
    (false);
    // 连接工厂
    (factory);
    // key 序列化方式
    (());
    // value 序列化方式
    (());
    // hash key 序列化方式
    (());
    // hash value 序列化方式
    (());
    // 配置完成
    ();
    return template;
}