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

猿天地發表於2020-03-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。

圖片

感興趣的可以關注下我的微信公眾號 猿天地,更多技術文章第一時間閱讀。我的GitHub也有一些開源的程式碼 github.com/yinjihuan

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

相關文章