RedisTemplate:我不背鍋,是你用錯了

  • 2020 年 3 月 11 日
  • 筆記

今天分享一個RedisTemplate的問題,感興趣的可以繼續看下去了,不感興趣的繼續撩妹去吧!

如下圖:一位朋友給了我一個報錯的圖片,為啥為啥取不到值?

我也有點懵,第一反應就是RedisTemplate和StringRedisTemplate會不會用的兩個不同的Connection,導致相同的Key一個能查到,一個不能查到。

經過反覆確認,Connection沒問題,是同一個,還是那句話:每個奇怪問題的背後一定有故事。

只能調試源碼了唄,還能怎麼辦。最後在redis.clients.jedis.BinaryJedis#hget中發現了問題,就是Redis壓根就沒有返回數據。

現在的問題就剩下為什麼StringRedisTemplate的查詢可以返回數據,RedisTemplate的查詢卻不能返回數據?

我們來屢一下StringRedisTemplate和RedisTemplate的關係,StringRedisTemplate繼承了RedisTemplate,是專門用於字元串操作。

RedisTemplate一般用於比較複雜的對象操作,區別就在於序列化的不同。

於是我用redis客戶端查看了存儲的數據格式,發現這個Hash的格式是字元串。

這也就是為什麼用StringRedisTemplate可以獲取到,估計存儲的時候就是用的StringRedisTemplate。

RedisTemplate默認的序列化方式是JDK序列化,格式不對。

於是查看了RedisTemplate的構造方式,發現就是序列化方式不一致。

於是將jdkSerializationRedisSerializer改成了stringSerializer。重新跑了一遍測試還是不行。於是我看了下RedisTemplate對象的資訊,如下:

valueSerializer是改過來了,但是hash有專門的序列化,還是JDK。

那就全部改成一樣的吧,如下:

然後就能獲取到了,個人感覺這個還是一個使用的問題,可能大家都以為這2個RedisTemplate是一樣的,沒什麼差別,所以才導致了本文出現的問題。

如果你夠細心,其實看下源碼就知道這2個類的區別了。

StringRedisTemplate構建的時候默認設置了所有的序列化方式為String,也就是說StringRedisTemplate的數據格式都是String。

RedisTemplate沒有設置的話就都是JDK。