Redis几种对象序列化的比较

关于Spring Data redis几种对象序列化的比较

RedisTemplate和StringRedisTemplate的区别

RedisTemplate和StringRedisTemplate的区别:

  1. 两者的关系是StringRedisTemplate继承RedisTemplate。
  2. 两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
  3. SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
    StringRedisTemplate默认采用的是String的序列化策略(StringRedisSerializer),保存的key和value都是采用此策略序列化保存的。
    RedisTemplate默认采用的是JDK的序列化策略(JdkSerializationRedisSerializer),保存的key和value都是采用此策略序列化保存的。

1,使用JdkSerializationRedisSerializer序列化

用JdkSerializationRedisSerializer序列化的话,被序列化的对象必须实现Serializable接口。

在存储内容时,除了属性的内容外还存了其它内容在里面,总长度长,且不容易阅读。

对于最下面的代码,存到redis里的内容如下:
redis 127.0.0.1:6379> get users/user1
"\xac\xed\x00\x05sr\x00!com.oreilly.springdata.redis.User\xb1\x1c \n\xcd\xed%\xd8\x02\x00\x02I\x00\x03ageL\x00\buserNamet\x00\x12Ljava/lang/String;xp\x00\x00\x00\x14t\x00\x05user1"

2,使用JacksonJsonRedisSerializer序列化

如果需要保存对象为json的话推荐使用JacksonJsonRedisSerializer,它不仅可以将对象序列化,还可以将对象转换为json字符串并保存到redis中,但需要和jackson配合一起使用。

用JacksonJsonRedisSerializer序列化的话,被序列化的对象不用实现Serializable接口。

Jackson是利用反射和getter和setter方法进行读取的,如果不想因为getter和setter方法来影响存储,就要使用注解来定义被序列化的对象。

Jackson序列化的结果清晰,容易阅读,而且存储字节少,速度快,推荐。

对于最下面的代码,存到redis里的内容如下:

redis 127.0.0.1:6379> get json/user1
"{"userName":"user1","age":20}"
redis 127.0.0.1:6379> strlen json/user1
(integer) 29

3,使用StringRedisSerializer序列化

一般如果key-value都是string的话,使用StringRedisSerializer就可以了

将RedisTemplate默认的序列化方式改为JacksonJsonRedisSerializer

StringRedisTemplate默认序列化方式不用改

RedisConfig

package com.cicdi.servertemplate.common.config.redis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;

/**
 * Created by HASEE on 2018/3/14.
 */
@Configuration
public class RedisConfig {

    @Bean
    public CachingConfigurerSupport keyGenerator() {
        return new MyCachingConfigurerSupport();
    }

    public class MyCachingConfigurerSupport extends CachingConfigurerSupport {
        @Override
        public KeyGenerator keyGenerator() {
            return new KeyGenerator() {
                @Override
                public Object generate(Object target, Method method, Object... params) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(target.getClass().getName());
                    sb.append(method.getName());
                    for (Object obj : params) {
                        sb.append(obj.toString());
                    }
                    return sb.toString();
                }
            };
        }
    }

    //缓存管理器
    @SuppressWarnings("rawtypes")
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
        //设置缓存过期时间
        rcm.setDefaultExpiration(300);//秒
        return rcm;
    }

    /**
     * 存入对象tostring后的信息
     */
    @Bean
    public RedisTemplate redisTemplate() {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(jedisConnectionFactory());
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);

        // hash的key也采用String的序列化方式,需要配置一下StringSerializer,不然key会乱码 /XX/XX
        template.setHashKeySerializer(stringRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);

        template.afterPropertiesSet();
        return template;
    }


//    /**
//     * 存入对象序列化信息
//     *
//     * @return
//     */
//    @Bean
//    public RedisTemplate redisSerizlizerObj1() {
//        RedisTemplate redisTemplate = new RedisTemplate<>();
//        redisTemplate.setConnectionFactory(jedisConnectionFactory());
//        // key采用String的序列化方式
//        redisTemplate.setKeySerializer(new StringRedisSerializer());
//        // value序列化方式采用jackson
//        redisTemplate.setValueSerializer(new RedisObjectSerializer());
//
//        // hash的key也采用String的序列化方式
//        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//        // hash的value序列化方式采用jackson
//        redisTemplate.setHashValueSerializer(new RedisObjectSerializer());
//        return redisTemplate;
//    }

    @Bean
    JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.setPassword("jihy");
        return jedisConnectionFactory;
    }

}

测试是否修改了序列化方式

         /*查看redisTemplate 的Serializer*/
        System.out.println(redisTemplate.getKeySerializer());
        System.out.println(redisTemplate.getValueSerializer());

            /*查看StringRedisTemplate 的Serializer*/
        System.out.println(stringRedisTemplate.getValueSerializer());
        System.out.println(stringRedisTemplate.getValueSerializer());

redis命令使用的是默认的序列化方式

Redis几种对象序列化的比较_第1张图片
1461379-06edc7428a812364_副本.png

内存中是以JdkSerializationRedisSerializer方式存储value,代码中设置的RedisTemplate的序列化方式是 Jackson2JsonRedisSerializer,那么通过
redisTemplate.opsForZSet().range(key, start, end)取值,set是0

内存中是以Jackson2JsonRedisSerializer 方式存储value,代码中设置的RedisTemplate的序列化方式是 JdkSerializationRedisSerializer(默认实现),那么通过
redisTemplate.opsForZSet().range(key, start, end)取值,set也是0

你可能感兴趣的:(Redis几种对象序列化的比较)