redis的序列化和反序列化
基础概念
redisFactory:redis的工厂类
redisTemplate:spring 封装了 RedisTemplate 对象来进行对redis的各种操作,它支持所有的 redis 原生的 api。
序列化
序列化能够使java的对象在传输和存储的过程中,能够成功的传输和读取。
如果redis不实现序列化的结果:
不实现序列化的话,存储的key字段会出现很多未识别字符:
然后key值出现的都是未识别字符,导致获取不了内容
redis实现序列化的方法
1. StringRedisSerializer
2. JdkSerializationRedisSerializer(默认使用是这个)
3. GenericToStringSerializer
4. Jackson2JsonRedisSerializer
5. OxmSerializer
6. GenericJackson2JsonRedisSerializer
7. 自定义序列化
所有的序列化的方法都基于接口RedisSerializer实现的,核心的不同就是serialize和deserialize这两个方法
序列化方法 | serialize核心 | deserialize核心 | 自我理解 |
---|---|---|---|
StringRedisSerializer | string == null ? null : string.getBytes(this.charset) | bytes == null ? null : new String(bytes, this.charset) | 序列化从String转为Byte[],反序列化反之 |
JdkSerializationRedisSerializer | (byte[])this.serializer.convert(object) | this.deserializer.convert(bytes) | 自我定义的Converter,默认是SerializingConverter和DeserializingConverter |
GenericToStringSerializer | (String)this.converter.convert(object, String.class) | this.converter.convert(string, this.type) | type是自定的Class对象,相当于class转String啦 |
Jackson2JsonRedisSerializer | this.objectMapper.writeValueAsBytes(t) | this.objectMapper.readValue(bytes, 0, bytes.length, this.javaType) | 和自定义的objectMapper有关,具体查看疑问中的解释(其实就是转json的方法) |
OxmSerializer | stream.toByteArray(); | this.unmarshaller.unmarshal(new StreamSource(new ByteArrayInputStream(bytes))); | 转流去做 |
GenericJackson2JsonRedisSerializer | this.mapper.writeValueAsBytes(source) | this.mapper.readValue(source, type) | 类似于Jackson2JsonRedisSerializer |
自定义序列化 | 自己重写 | 自己重写 | 自定义 |
重要代码解析
设置redisTemplate
@Bean
public RedisTemplate<String,Object> redisTemplate(){
StringRedisSerializer stringRedisSerializer=new StringRedisSerializer();
JdkSerializationRedisSerializer jdkSerializationRedisSerializer=new JdkSerializationRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
/*
设置objectMapper;转换java对象的时候使用的
*/
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置key:value和hashKey:hashValue的序列化的方式
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
//初始实例化redisTemplate
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
疑问
1.代码疑问一
Q:jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
A:ObjectMapper实现序列和反序列化,传输在redis里面的数据。
设置了这个jackson2JsonRedisSerializer会在deserialize中调用this.objectMapper.readValue()
- 代码疑问二
Q:redisTemplate.afterPropertiesSet();
A:初始化完成序列化的方法
附件
jedis实现redis的客户端
Q:jedis可以实现序列化吗?
A:jedis可以实现,但是它只能支持byte数组的传入和传出,所以需要自己实现序列化和反序列化去做。
jedis的序列化和反序列化的实现
博客