SpringBoot中RedisTemplate序列化的几种方式

时间:2025-02-22 09:03:38

SpringBoot中RedisTemplate序列化的几种方式
SpringBoot2.1.5
Redis5.0.3

问题

当调用opsForValue方法时会传入当前redistemplate对象,以keySerializer为例,它默认为null,如果等于null就被赋值dafaultSerializer,默认dafaultSerializer也为空,最终keySerializer就被赋值为JdkSerializationRedisSerializer,所以没有设置序列化方式的时候redistemplate使用的序列化方式为JdkSerializationRedisSerializer,所以我们存入key前面会带上一串东西,而StringRedisTemplate使用的是 StringRedisSerializer,序列化的方式不一样,所以使用的时候key就不会出现一串字符串。

RedisTemplate的序列化类型

SpringBoot提供的Redis存储序列化方式,常用的有以下几种:
JdkSerializationRedisSerializer:将数据序列化为对象
StringRedisSerializer:将数据序列化为字符串
Jackson2JsonRedisSerializer:将数据序列化为json
GenericJackson2JsonRedisSerializer

三、Jackson2JsonRedisSerializer

就序列化和反序列化性能来说,Jackson2JsonRedisSerializer方式效率是最高的,同时在redis中也有很好的可读性。

序列化处理类

import .Jackson2JsonRedisSerializer;
import ;
import ;
import ;
import ;

/**
 * Redis对json序列化处理
 */
@Configuration
public class RedisConfig_JacksonSerializer
{
	@Bean
	public RedisTemplate <String, Object> getRedisTemplate(RedisConnectionFactory connectionFactory)
	{
		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
		(connectionFactory);
		// 使用Jackson2JsonRedisSerialize替换默认序列化方式
		Jackson2JsonRedisSerializer<?> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>();
		StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
		ObjectMapper om = new ObjectMapper();
		(, );
		//启用默认的类型
		(.NON_FINAL);
		//序列化类,对象映射设置
		(om);
		(stringRedisSerializer);
		(jackson2JsonRedisSerializer);
		(stringRedisSerializer);
		(jackson2JsonRedisSerializer);
		();
		return redisTemplate;
	}
}

Redis查询结果


[root@localhost ~]# redis-cli -c -h 192.168.236.128 -p 6379 -a 123456
192.168.236.128:6380> keys *
1) "dept"
192.168.236.128:6380> hget dept id
"\"1006\""
192.168.236.128:6380> hget dept name
"\"zhangsan6\""
192.168.236.128:6380> hget dept level
"6"

二、StringRedisSerializer

Springboot提供的StringRedisTemplate模板操作是用StringRedisSerializer来进行序列化。该序列化方式只能保存字符串,不能保存对象。

序列化处理类

import ;
import ;
import ;
import ;
import ;

@Configuration
public class RedisConfig_StringSerializer {
	@Bean
	public RedisTemplate<String, Object> getRedisTemplate(RedisConnectionFactory connectionFactory) 
	{
		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
		RedisSerializer<?> stringSerializer = new StringRedisSerializer();
		(connectionFactory);
		(stringSerializer);
		(stringSerializer);
		(stringSerializer);
		(stringSerializer);
		return redisTemplate;
	}
}

Redis查询结果

[root@localhost conf]# redis-cli -c -h 192.168.236.128 -p 6380 -a 123456
192.168.236.128:6380> keys *
1) "dept"
192.168.236.128:6380> hget dept id
"1006"
192.168.236.128:6380> hget dept name
"zhangsan6"
192.168.236.128:6380> hget dept level
"6"

一、JdkSerializationRedisSerializer

spring-data-redis的RedisTemplate模板类在操作redis时默认使用JdkSerializationRedisSerializer进行序列化,并在Redis中存储序列化后的二进制字节。所以就占用存储空间来说,JdkSerializationRedisSerializer方式序列化之后长度是最小的。

序列化处理类

SpringData提供的RedisTemplate只支持基本类型的操作,不能处理对象的存储。为了方便对象的操作,我们需要自定义一个RedisTemplate来操作对象。

自定义处理对象的存储,使用RedisTemplate模板加载序列化工具类RedisObjectSerializer。

import ;
import ;
import ;
import ;
import ;

/**
 * JDK序列化处理—自定义处理对象的存储
 * 使用RedisTemplate模板加载序列化工具类RedisObjectSerializer
 */
@Configuration
public class RedisConfig_JDKSerializer
{
	@Bean
	public RedisTemplate<Object, Object> getRedisTemplate(RedisConnectionFactory connectionFactory)
	{
		RedisTemplate<Object, Object> rt = new RedisTemplate<>();
		(connectionFactory);
		(new StringRedisSerializer());
		(new RedisObjectSerializer());
		return rt;
	}
}

/**
 * 自定义 
 */
import ;
import ;
import ;
import ;
import ;

public class RedisObjectSerializer implements RedisSerializer<Object>
{
	private Converter<Object, byte[]> serializingConverter = new SerializingConverter();
	private Converter<byte[], Object> deserializingConverter = new DeserializingConverter();
	
	@Override
	public byte[] serialize(Object obj) throws SerializationException
	{
		if(obj == null) {
			return new byte[0];
		}
		//将对象转换为字节数组
		return (obj);
	}

	@Override
	public Object deserialize(byte[] bytes) throws SerializationException
	{
		if (bytes == null ||  == 0)
			return null;
		return (bytes);
	}
}

Redis查询结果(旧的)

[root@localhost ~]# redis-cli -c -h 192.168.236.128 -p 6380 -a 123456
192.168.236.128:6380> keys * 
1) "\xac\xed\x00\x05t\x00\x04dept"

192.168.236.128:6380> hget dept id
"\xac\xed\x00\x05t\x00\x041002"

192.168.236.128:6380> hget dept name
"\xac\xed\x00\x05t\x00\tzhangsan2"

192.168.236.128:6380> hget dept level
"\xac\xed\x00\x05sr\x00\\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x02"

Junit测试

@RunWith()
@SpringBootTest(classes = {  })
public class AppTest
{
	@Autowired
	private RedisTemplate<String, Object> redisTemplate;
	
	@Test
	public void test() throws Exception
	{
		().put("dept", "id", "1006");
		().put("dept", "name", "zhangsan6");
		().put("dept", "level", 6); 
		(().keys("dept"));
		(().size("dept"));
		(().values("dept"));
	}
}

参考 资料

Springboot2整合Redis以及jackson序列化
/zaincs/article/details/84399584

基于Spring的项目中Redis存储对象使用Jackson序列化方式
/

SpringBoot整合Redis序列化配置
/fx9590/article/details/99424568

在Service的实现类中单独指定Serializer
/EasonJim/p/

Springboot中redis序列化问题分析
/u012031408/article/details/89478241