微服务学习系列9:RedisTemplate

系列文章目录


目录

系列文章目录

前言

一、序列化的方法

 Jackson2JsonRedisSerializer

GenericJackson2JsonRedisSerializer

JdkSerializationRedisSerializer

StringRedisSerializer 

GenericFastJsonRedisSerializer

FastJsonRedisSerializer 

二、序列化类的对比序列化结果



前言

当我们的数据存储到 Redis 的时候,我们的键(key)和值(value)都是通过 Spring 提供的 Serializer 序列化到数据库的。

RedisTemplate 默认使用的是 JdkSerializationRedisSerializer。
StringRedisTemplate 默认使用的是 StringRedisSerializer。


一、序列化的方法

 Jackson2JsonRedisSerializer

jackson-json工具提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。因为jackson工具在序列化和反序列化时,需要明确指定Class类型,因此此策略封装起来稍微复杂。【需要jackson-mapper-asl工具支持】

序列化带泛型的数据时,会以map的结构进行存储,反序列化是不能将map解析成对象 解决办法序列化存储时,转成JSON字符串

@Bean("myRedisTemplate")
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

        //设置忽略 不认识的字段 https://blog.csdn.net/u012693823/article/details/123256574
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);

        //设置value的序列化规则和 key的序列化规则
        RedisSerializer stringSerializer = new StringRedisSerializer(StandardCharsets.UTF_8);
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(serializer);
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    } 
  
{
    "id":1,
    "name":"yyp",
    "userType":1
}

GenericJackson2JsonRedisSerializer

用GenericJackson2JsonRedisSerializer序列化时,会保存序列化的对象的包名和类名,反序列化时以这个作为标示就可以反序列化成指定的对象。

使用GenericJacksonRedisSerializer比Jackson2JsonRedisSerializer效率低,占用内存高。

LocalDate这是java8新增的类,GenericJackson2JsonRedisSerializer序列化方式无法识别

    @Bean("myRedisTemplate")
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        //设置value的序列化规则和 key的序列化规则
        RedisSerializer stringSerializer = new StringRedisSerializer(StandardCharsets.UTF_8);
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(serializer);
        redisTemplate.afterPropertiesSet();

        return redisTemplate;

    } 
  
{
    "@class":"com.xinwu.shushan.author.test.service.CacheTest$User",
    "id":1,
    "name":"yyp",
    "userType":1
}

JdkSerializationRedisSerializer

POJO对象的存取场景,使用JDK本身序列化机制,将pojo类通过ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。是目前默认的序列化策略。

使用JdkSerializationRedisSerializer序列化的Bean必须实现Serializable接口

��sr4com.xinwu.shushan.author.test.service.CacheTest$User���^�#�LidtLjava/lang/Integer;LnametLjava/lang/String;LuserTypeq~xpsrjava.lang.Integer⠤���8Ivaluexrjava.lang.Number������xptyypq~

StringRedisSerializer 

Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成string,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。

不能序列化Bean,只能序列化字符串类型的数据,如果value都是字符串类型,可以用该方式序列化

$User cannot be cast to java.lang.String 

GenericFastJsonRedisSerializer

fastjson 为RedisSerializer 接口提供了两个实现类GenericFastJsonRedisSerializer 和FastJsonRedisSerializer

一种Java bean与json之间的转换,同时也需要指定Class类型。

不支持设置FastJsonConfig 特性, 生成json串会多一个type参数, type的值为class 名称。

    @Bean("myRedisTemplate")
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        GenericFastJsonRedisSerializer serializer = new GenericFastJsonRedisSerializer();
        //设置value的序列化规则和 key的序列化规则
        RedisSerializer stringSerializer = new StringRedisSerializer(StandardCharsets.UTF_8);
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(serializer);
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }
{
    "@type":"com.xinwu.shushan.author.test.service.CacheTest$User",
    "id":1,
    "name":"yyp",
    "userType":1
}

FastJsonRedisSerializer 

使用 Alibaba Fastjson 处理。支持设置FastJsonCofing 特性, 默认生成json串不包含type属性。

    @Bean("myRedisTemplate")
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        FastJsonRedisSerializer serializer = new FastJsonRedisSerializer<>(Object.class);
        //设置value的序列化规则和 key的序列化规则
        RedisSerializer stringSerializer = new StringRedisSerializer(StandardCharsets.UTF_8);
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(serializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    } 
  
{
    "id":1,
    "name":"yyp",
    "userType":1
}

二、序列化类的对比序列化结果

数据结构 ValueSerializer 序列化类 序列化前 序列化后
Key/Value ValueSerializer StringRedisSerializer 1 1
ValueSerializer Jackson2JsonRedisSerializer 1 "1"
ValueSerializer JdkSerializationRedisSerializer 1 ��t1

  • 用StringRedisSerializer进行序列化的值,在Java和Redis中保存的内容是一样的。
  • 用Jackson2JsonRedisSerializer进行序列化的值,在Redis中保存的内容,比Java中多了一对双引号。
  • 用JdkSerializationRedisSerializer进行序列化的值,对于Key-Value的Value来说,是在Redis中是不可读的。对于Hash的Value来说,比Java的内容多了一些字符。

你可能感兴趣的:(学习,java,mybatis)