SpringBoot中RedisTemplate序列化的几种方式

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 org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Redis对json序列化处理
 */
@Configuration
public class RedisConfig_JacksonSerializer
{
	@Bean
	public RedisTemplate <String, Object> getRedisTemplate(RedisConnectionFactory connectionFactory)
	{
		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
		redisTemplate.setConnectionFactory(connectionFactory);
		// 使用Jackson2JsonRedisSerialize替换默认序列化方式
		Jackson2JsonRedisSerializer<?> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
		StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
		ObjectMapper om = new ObjectMapper();
		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		//启用默认的类型
		om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
		//序列化类,对象映射设置
		jackson2JsonRedisSerializer.setObjectMapper(om);
		redisTemplate.setKeySerializer(stringRedisSerializer);
		redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
		redisTemplate.setHashKeySerializer(stringRedisSerializer);
		redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
		redisTemplate.afterPropertiesSet();
		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 org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig_StringSerializer {
	@Bean
	public RedisTemplate<String, Object> getRedisTemplate(RedisConnectionFactory connectionFactory) 
	{
		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
		RedisSerializer<?> stringSerializer = new StringRedisSerializer();
		redisTemplate.setConnectionFactory(connectionFactory);
		redisTemplate.setKeySerializer(stringSerializer);
		redisTemplate.setValueSerializer(stringSerializer);
		redisTemplate.setHashKeySerializer(stringSerializer);
		redisTemplate.setHashValueSerializer(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 org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

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

/**
 * 自定义 RedisObjectSerializer.java
 */
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.core.serializer.support.SerializingConverter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

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 this.serializingConverter.convert(obj);
	}

	@Override
	public Object deserialize(byte[] bytes) throws SerializationException
	{
		if (bytes == null || bytes.length == 0)
			return null;
		return this.deserializingConverter.convert(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\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x02"

Junit测试

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

参考 资料

Springboot2整合Redis以及jackson序列化
https://blog.csdn.net/zaincs/article/details/84399584

基于Spring的项目中Redis存储对象使用Jackson序列化方式
https://www.zifangsky.cn/1366.html

SpringBoot整合Redis序列化配置
https://blog.csdn.net/fx9590/article/details/99424568

在Service的实现类中单独指定Serializer
https://www.cnblogs.com/EasonJim/p/7805665.html

Springboot中redis序列化问题分析
https://blog.csdn.net/u012031408/article/details/89478241

  • 3
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值