系列文章目录
目录
GenericJackson2JsonRedisSerializer
JdkSerializationRedisSerializer
GenericFastJsonRedisSerializer
前言
当我们的数据存储到 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<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
Jackson2JsonRedisSerializer<Object> 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<String> 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<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
//设置value的序列化规则和 key的序列化规则
RedisSerializer<String> 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<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
GenericFastJsonRedisSerializer serializer = new GenericFastJsonRedisSerializer();
//设置value的序列化规则和 key的序列化规则
RedisSerializer<String> 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<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
FastJsonRedisSerializer<Object> serializer = new FastJsonRedisSerializer<>(Object.class);
//设置value的序列化规则和 key的序列化规则
RedisSerializer<String> 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的内容多了一些字符。