1. 程式人生 > >RedisTemplate:我不背鍋,是你用錯了

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

今天分享一個RedisTemplate的問題,感興趣的可以繼續看下去了,不感興趣的繼續撩妹去吧! 如下圖:一位朋友給了我一個報錯的圖片,為啥為啥取不到值? ![](https://img2020.cnblogs.com/blog/1618095/202003/1618095-20200311134847500-360721412.png) 我也有點懵,第一反應就是RedisTemplate和StringRedisTemplate會不會用的兩個不同的Connection,導致相同的Key一個能查到,一個不能查到。 經過反覆確認,Connection沒問題,是同一個,還是那句話:**每個奇怪問題的背後一定有故事。** 只能除錯原始碼了唄,還能怎麼辦。最後在redis.clients.jedis.BinaryJedis#hget中發現了問題,就是Redis壓根就沒有返回資料。 現在的問題就剩下為什麼StringRedisTemplate的查詢可以返回資料,RedisTemplate的查詢卻不能返回資料? 我們來屢一下StringRedisTemplate和RedisTemplate的關係,StringRedisTemplate繼承了RedisTemplate,是專門用於字串操作。 RedisTemplate一般用於比較複雜的物件操作,區別就在於序列化的不同。 於是我用redis客戶端查看了儲存的資料格式,發現這個Hash的格式是字串。 ![](https://img2020.cnblogs.com/blog/1618095/202003/1618095-20200311134904174-1934116272.png) 這也就是為什麼用StringRedisTemplate可以獲取到,估計儲存的時候就是用的StringRedisTemplate。 RedisTemplate預設的序列化方式是JDK序列化,格式不對。 於是查看了RedisTemplate的構造方式,發現就是序列化方式不一致。 ![](https://img2020.cnblogs.com/blog/1618095/202003/1618095-20200311134918615-1837836397.png) 於是將jdkSerializationRedisSerializer改成了stringSerializer。重新跑了一遍測試還是不行。於是我看了下RedisTemplate物件的資訊,如下: ![](https://img2020.cnblogs.com/blog/1618095/202003/1618095-20200311134935423-156480521.png) valueSerializer是改過來了,但是hash有專門的序列化,還是JDK。 那就全部改成一樣的吧,如下: ![](https://img2020.cnblogs.com/blog/1618095/202003/1618095-20200311134949586-1966854013.png) 然後就能獲取到了,個人感覺這個還是一個使用的問題,可能大家都以為這2個RedisTemplate是一樣的,沒什麼差別,所以才導致了本文出現的問題。 如果你夠細心,其實看下原始碼就知道這2個類的區別了。 ![](https://img2020.cnblogs.com/blog/1618095/202003/1618095-20200311135003703-1755343256.png) StringRedisTemplate構建的時候預設設定了所有的序列化方式為String,也就是說StringRedisTemplate的資料格式都是String。 RedisTemplate沒有設定的話就都是JDK。 ![](https://img2020.cnblogs.com/blog/1618095/202003/1618095-20200311135027450-18417667