* redis虽然提供了对list set hash等数据类型的支持,但是没有提供对POJO对象的支持,底层都是把对象序列化后再以字符串的方式存储的。*
Spring data提供了若干个Serializer,主要包括:
JdkSerializationRedisSerializer——使用Java自带的序列化机制将对象序列化为一个字符串
OxmSerializer——将对象序列化为xml字符串
Jackson2JsonRedisSerializer——将对象序列化为json字符串
下面分别测试这三种序列化,看看效果:
实体类User——将要保存到redis的对象
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "user")
public class User implements Serializable{
private static final long serialVersionUID = 5403379425407254942L;
@XmlAttribute
private String userName;
@XmlAttribute
private int age;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
RootConfig配置类:
@Configuration
@ComponentScan(basePackages="com.redis.*")
public class RootConfig {
/**
* 配置redis连接工厂
* @return
*/
@Bean
public RedisConnectionFactory redisConnectionFactory(){
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName("localhost");
factory.setPort(6379);
factory.afterPropertiesSet();
return factory;
}
/**
* Spring的RedisTemplate
* @return
*/
@Bean
public RedisTemplate
RedisTemplate
template.setConnectionFactory(redisConnectionFactory());
return template;
}
@Bean
public OxmSerializer oxmSerializer(){
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
Map
properties.put(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);//放置xml自动缩进属性
properties.put(Marshaller.JAXB_ENCODING, "utf-8");
jaxb2Marshaller.setClassesToBeBound(User.class);//映射的xml类放入JAXB环境中
jaxb2Marshaller.setMarshallerProperties(properties);//设置Marshaller属性
return new OxmSerializer(jaxb2Marshaller, jaxb2Marshaller);
}
//下面是简单类型的序列化类
public static enum StringSerializer implements RedisSerializer
INSTANCE;
@Override
public byte[] serialize(String t) throws SerializationException {
return (null != t ? t.getBytes() : new byte[0]);
}
@Override
public String deserialize(byte[] bytes) throws SerializationException {
if(bytes.length > 0){
return new String(bytes);
} else {
return null;
}
}
}
public static enum LongSerializer implements RedisSerializer
INSTANCE;
@Override
public byte[] serialize(Long t) throws SerializationException {
if(null != t){
return t.toString().getBytes();
}else {
return new byte[0];
}
}
@Override
public Long deserialize(byte[] bytes) throws SerializationException {
if(bytes.length > 0){
return Long.parseLong(new String(bytes));
}else {
return null;
}
}
}
public static enum IntSerializer implements RedisSerializer
INSTANCE;
@Override
public byte[] serialize(Integer t) throws SerializationException {
if(null != t){
return t.toString().getBytes();
}else {
return new byte[0];
}
}
@Override
public Integer deserialize(byte[] bytes) throws SerializationException {
if(bytes.length > 0){
return Integer.parseInt(new String(bytes));
}else {
return null;
}
}
}
}
测试用例:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={RootConfig.class,WebConfig.class})
@WebAppConfiguration
public class KeyValueSerializersTest {
@Autowired
private RedisConnectionFactory connectionFactory;
@Autowired
private OxmSerializer oxmSerializer;
@Test
public void testJdkSerializer(){
RedisTemplate
redis.setConnectionFactory(connectionFactory);
redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);
redis.setValueSerializer(new JdkSerializationRedisSerializer());
redis.afterPropertiesSet();
ValueOperations
User user1 = new User();
user1.setUserName("xuexiaoqiang");
user1.setAge(25);
String key1 = "jdk/user1";
User user11 = null;
long begin = System.currentTimeMillis();
for(int i = 0; i < 100; i++){
ops.set(key1, user1);
user11 = (User) ops.get(key1);
}
long time = System.currentTimeMillis() - begin;
System.out.println("jdk time: "+time);
System.out.println(user11.getUserName());
}
@Test
public void testOxmSerializer() {
RedisTemplate
redis.setConnectionFactory(connectionFactory);
redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);
redis.setValueSerializer(oxmSerializer);
redis.afterPropertiesSet();
ValueOperations
User user1 = new User();
user1.setUserName("xuexiaoqiang");
user1.setAge(25);
String key1 = "oxm/user1";
User user11 = null;
long begin = System.currentTimeMillis();
for(int i = 0; i < 100; i++){
ops.set(key1, user1);
user11 = (User) ops.get(key1);
}
long time = System.currentTimeMillis() - begin;
System.out.println("oxm time: "+time);
System.out.println(user11.getUserName());
}
@Test
public void testJacksonSerialiable() {
RedisTemplate
redis.setConnectionFactory(connectionFactory);
redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);
redis.setValueSerializer(new Jackson2JsonRedisSerializer
redis.afterPropertiesSet();
ValueOperations
User user1 = new User();
user1.setUserName("xuexiaoqiang");
user1.setAge(25);
String key1 = "json/user1";
User user11 = null;
long begin = System.currentTimeMillis();
for(int i = 0; i < 100; i++){
ops.set(key1, user1);
user11 = (User) ops.get(key1);
}
long time = System.currentTimeMillis() - begin;
System.out.println("json time: "+time);
System.out.println(user11.getUserName());
}
}
结果:
testJdkSerializer()方法:
控制台打印:
jdk time: 68
xuexiaoqiang
redis中:
127.0.0.1:6379> get jdk/user1
"\xac\xed\x00\x05sr\x00\x15com.redis.entity.UserJ\xfc\xa8\xf5\x86\r\xc1\x9e\x02\x00\x02I\x00\x03ageL\x00\buserNamet\x00\x12Ljava/lang/String;xp\x00\x00\x00\x19t\x00\x0cxuexiaoqiang"
testOxmSerializer()方法:
控制台输出:
oxm time: 471
xuexiaoqiang
redis:
127.0.0.1:6379> get oxm/user1
"\n
testJacksonSerialiable()方法:
控制台输出:
json time: 97
xuexiaoqiang
redis:
127.0.0.1:6379> get json/user1
"{\"userName\":\"xuexiaoqiang\",\"age\":25}"
从时间上来看,JdkSerializationRedisSerializer是最高效的,但是从序列化的结果来看,json占用的内存最小。所以个人认为最优方案是使用JSON序列化。
demo:
转载自:http://blog.csdn.net/csdn_xuexiaoqiang/article/details/73650046