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