Spring Data Redis提供的几种序列化的比较

来源:互联网 发布:人工神经网络算法教程 编辑:程序博客网 时间:2024/05/20 21:46

* 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<String, Object> redisTemplate(){        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();        template.setConnectionFactory(redisConnectionFactory());        return template;    }    @Bean    public OxmSerializer oxmSerializer(){        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();        Map<String, Object> properties = new HashMap<String, Object>();//创建映射,用于设置Marshaller属性          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<String> {        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<Long> {        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<Integer> {        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})@WebAppConfigurationpublic class KeyValueSerializersTest {    @Autowired    private RedisConnectionFactory connectionFactory;    @Autowired    private OxmSerializer oxmSerializer;    @Test    public void testJdkSerializer(){        RedisTemplate<String, Serializable> redis = new RedisTemplate<String, Serializable>();        redis.setConnectionFactory(connectionFactory);        redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);        redis.setValueSerializer(new JdkSerializationRedisSerializer());        redis.afterPropertiesSet();        ValueOperations<String, Serializable> ops = redis.opsForValue();        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<String, Object> redis = new RedisTemplate<String, Object>();        redis.setConnectionFactory(connectionFactory);        redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);        redis.setValueSerializer(oxmSerializer);        redis.afterPropertiesSet();        ValueOperations<String, Object> ops = redis.opsForValue();        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<String, Object> redis = new RedisTemplate<String, Object>();        redis.setConnectionFactory(connectionFactory);        redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);        redis.setValueSerializer(new Jackson2JsonRedisSerializer<User>(User.class));        redis.afterPropertiesSet();        ValueOperations<String, Object> ops = redis.opsForValue();        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: 68xuexiaoqiang

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: 471xuexiaoqiang

redis:

127.0.0.1:6379> get oxm/user1"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n<user userName=\"xuexiaoqiang\" age=\"25\"/>\n"

testJacksonSerialiable()方法:
控制台输出:

json time: 97xuexiaoqiang

redis:

127.0.0.1:6379> get json/user1"{\"userName\":\"xuexiaoqiang\",\"age\":25}"

从时间上来看,JdkSerializationRedisSerializer是最高效的,但是从序列化的结果来看,json占用的内存最小。所以个人认为最优方案是使用JSON序列化。

demo:

原创粉丝点击