1. 程式人生 > >Redis系列--7、RedisTemplate和 Serializer詳解

Redis系列--7、RedisTemplate和 Serializer詳解

redistemplate serializer詳解

<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
   <property name="connectionFactory" ref="connectionFactory" />
      <!--如果不配置Serializer,那麽存儲的時候智能使用String,如果用User類型存儲,那麽會提示錯誤User can‘t cast to String!!!  -->       
   <property name="keySerializer">
      <bean
        class="org.springframework.data.redis.serializer.StringRedisSerializer" />
   </property>
   <property name="valueSerializer">
      <bean
        class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
   </property>
</bean>


可以看到我在代碼中註釋掉了一段代碼,現在可以解釋上面留下的兩個問題了,第一個是在redis.xml中配置redistemplate的時候,同時配置了兩個Serializer:keySerializer實現了StringRedisSerializer,valueSerializer實現了JdkSerializationRedisSerializer。

  一、為什麽要使用Serializer

  因為redis是以key-value的形式將數據存在內存中,key就是簡單的string,key似乎沒有長度限制,不過原則上應該盡可能的短小且可讀性強,無論是否基於持久存儲,key在服務的整個生命周期中都會在內存中,因此減小key的尺寸可以有效的節約內存,同時也能優化key檢索的效率。

  value在redis中,存儲層面仍然基於string,在邏輯層面,可以是string/set/list/map,不過redis為了性能考慮,使用不同的“encoding”數據結構類型來表示它們。(例如:linkedlist,ziplist等)。

  所以可以理解為,其實redis在存儲數據時,都把數據轉化成了byte[]數組的形式,那麽在存取數據時,需要將數據格式進行轉化,那麽就要用到序列化和反序列化了,這也就是為什麽需要配置Serializer的原因。

  二、SDR支持的序列化策略:

(詳細可查閱API文檔)

  • JdkSerializationRedisSerializer

  • StringRedisSerializer

  • JacksonJsonRedisSerializer:

  • OxmSerializer:

  其中JdkSerializationRedisSerializer和StringRedisSerializer是最基礎的序列化策略,其中“JacksonJsonRedisSerializer”與“OxmSerializer”都是基於stirng存儲,因此它們是較為“高級”的序列化(最終還是使用string解析以及構建java對象)。

  基本推薦使用JdkSerializationRedisSerializer和StringRedisSerializer,因為其他兩個序列化策略使用起來配置很麻煩,如果實在有需要序列化成Json和XML格式,可以使用java代碼將String轉化成相應的Json和XML。

  三、使用Serializer

  在本項目中,是在配置文件中直接配置了相應的Serializer,key用的是StringRedisSerializer,value用的是JdkSerializationRedisSerializer,因為在此項目中,key為userId,為String類型,value為user為java類,即POJO,所以使用JdkSerializationRedisSerializer。

  在redistemplate中直接配置Serializer當然比較方便,因為在後面想redis中存取數據時,就不用再次配置Serializer,但是這僅限於只有一種數據類型的情況,比如在本項目中只有<String userId,User user>類型的數據需要存儲,如果有多種數據類型時,在配置文件中配置就顯得不方便了,那麽我們可以在存取數據時,即Service的實現類存取數據操作時分別指定相應的Serializer。


所以在編程時有兩種選擇:

1.在redistemplate中配置Serializer(本項目即采用這種方式)

ValueOperations<String, User> valueops = redisTemplate.opsForValue();
valueops.set(user.getId(), user);

2.不在redistemplate中配置Serializer,而是在Service的實現類中單獨指定Serializer。就如同UserOperationsServiceImpl.java註釋的代碼:

boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
      public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
          RedisSerializer<String> redisSerializer = redisTemplate .getStringSerializer();
         byte[] key = redisSerializer.serialize(user.getId());
          byte[] value = redisSerializer.serialize(user.getName());
          return redisConnection.setNX(key, value); } });
     return result;
 }






本文出自 “風之痕_雪虎” 博客,請務必保留此出處http://snowtiger.blog.51cto.com/12931578/1932732

Redis系列--7、RedisTemplate和 Serializer詳解