php redis 对象序列化,Redis几种对象序列化的比较

RedisTemplate和StringRedisTemplate的区别:

两者的关系是StringRedisTemplate继承RedisTemplate。

两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。

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命令使用的是默认的序列化方式

e72ec3681fea

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值