1. 程式人生 > >spring-data-redis 使用過程中需要注意的一點(序列化選擇)

spring-data-redis 使用過程中需要注意的一點(序列化選擇)

在專案中需要用到redis做快取,於是採用spring-data-redis,並且打算自己封裝一個redis的靜態工具類。後來在進行單元測試的過程中發現了一個容易出錯的地方,於是打算記錄下來,並分享給各位朋友。

這裡主要說下碰到的問題,首先,採用了spring-data-redis(以下簡稱SDR)中的Template進行redis的操作。

因為考慮到後期的使用場景,於是同時採用了StringRedisTemplate和RedisTemplate,並且對儲存String與儲存Java物件採用不同的Template進行了簡單的封裝。

首先是測試 儲存與取出方法。分別用不同的template可以完美通過。

然後在測試刪除的方法中,測試出現了問題。

問題如下:

在採用StringRedisTemplate進行儲存的資料,用StringRedisTemplate去刪除可以成功刪除。

在採用RedisTemplate進行儲存的資料,用RedisTemplate去刪除也可以刪除成功。

在用RedisTemplate去刪除StringRedisTemplate儲存的資料時,發現刪除失敗。

在用StringRedisTemplate去刪除RedisTemplate儲存的資料時,刪除失敗。

因為,需要封裝一套通用的刪除方法,並且需要封裝一個批量刪除的方法。所以研究了下問題出現的原因。

經過檢視SDR官方給出的文件,發現是因為序列化策略的問題。

這裡簡單說下:

SDR預設採用的序列化策略有兩種,一種是String的序列化策略,一種是JDK的序列化策略。

StringRedisTemplate預設採用的是String的序列化策略,儲存的key和value都是採用此策略序列化儲存的。StringRedisSerializer

RedisTemplate預設採用的是JDK的序列化策略,儲存的key和value都是採用此策略序列化儲存的。JdkSerializationRedisSerializer

就是因為序列化策略的不同,即使是同一個key用不同的Template去序列化,結果是不同的。所以根據key去刪除資料的時候就出現了刪除失敗的問題。

解決方法如下,手動指定RedisTemplate的key的序列化策略

<!-- redis 序列化策略 ,通常情況下key值採用String序列化策略, -->  
<!-- 如果不指定序列化策略,StringRedisTemplate的key和value都將採用String序列化策略; -->  
<!-- 但是RedisTemplate的key和value都將採用JDK序列化 這樣就會出現採用不同template儲存的資料不能用同一個template刪除的問題 -->  
<bean id="stringRedisSerializer"   
    class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
  
<bean id='redisWriteTemplate' class="org.springframework.data.redis.core.RedisTemplate">  
    <property name="connectionFactory" ref="jedisWriteConnectionFactory" />  
    <property name="keySerializer" ref="stringRedisSerializer" />  
    <property name="hashKeySerializer" ref="stringRedisSerializer" />  
</bean>  

這樣就能完美的刪除了。

這裡推薦將所有Template的key都採用String的序列化方式,而value的序列化方式可以採用不同的序列化方式。(jreids自動選擇)(這樣還有一個好處就是不必string的也採用jdk的序列化從而導常用資料格式致為了儲存資料結構浪費空間)

另外 出來這兩個序列化方式之外,SDR還提供了

JacksonJsonRedisSerializer Jackson2JsonRedisSerializer OxmSerializer

等序列化方法,大家可以分別採用各種序列化方式做一些試驗。