今天分享一個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。