Redis整合SpringBoot
在測試中,推薦使用我們自己重寫的RedisTemplate
RedisTemplate 序列化問題
1.為何Redis整合Spring時需要在存儲時序列化?
在JAVA中,一個對象的信息一般並非連續的,在存儲的時候我們會需要提煉為一個連續的數據串(通常是byte array數組或者字符串),這個也正是序列化的字面意思。這樣才能將你的對象信息存儲起來,或者用於傳輸。
任何存儲都需要序列化。只不過常規你在用DB一類存儲的時候,這個事情DB幫你在內部搞定了(直接把SQL帶有類型的數據轉換成內部序列化的格式,存儲;讀取時再解析出來)。
而Redis並不會幫你做這個事情。當你用Redis的key和value時,value對於redis來講就是個byte array。你要自己負責把你的數據結構轉換成byte array,等讀取時再讀出來。
一個特例是字符串,因為字符串自己幾乎就已經是byte array了,所以不需要自己處理。
因此當你要用redis存一個東西,你可能會遇到
- 如果是boolean類型的true/false;你要自己定義redis里怎么表示true和false。比如你可以用1代表true,0代表false;也可以用“true”這個字符串代表true,“false”這個字符串代表false。
- 如果是數字,可以直接存儲數字的字符串表示(5 --> '5'),然后讀取時再把數字字符串轉回來(parseInt/parseDouble/...)。
- 如果是時間/日期,可以自己定義一種字符串表達,比如epoc timestamp這個數的字符串表示,又或者是ISO8601的格式。
- 如果是一個復雜的數據結構,你需要自己用某種序列化格式來存,可以是json, protobuf, avro, java serialization, python pickle……
回到Spring這邊。Spring的redisTemplate默認會使用java serialization做序列化。你也可以用StringRedisTemplate,那么你set的所有數據都會被toString一下再存到redis里。但這個toString不一定能反解析的回來……
總之簡單一句話,你要形成一個序列化的約定,確保存進去的東西能解析回來不出錯。也許你可以和你的team商量一個規范。
2.默認序列化方式:Jdk序列化(不推薦)
不建議試用默認java的對象序列化,推薦自己序列化為json后存儲,否則各種兼容問題
3.推薦序列化方式:key使用StringRedisSerializer, value使用Jackson2JsonRedisSerializer
為什么key和value用的serializer不同?
因為我們在自定義RedisTemplate時,泛型定義為<String, Object>。
key都是String,就可以使用簡單的StringRedisSerializer來做簡單的序列化,反序列化即可;
而value是Object,略微復雜,僅僅靠StringRedisSerializer(--類似toString()的邏輯,序列化后不一定能反序列化成功...)是不行的。
4.所有pojo類都要序列化
redis儲存對象,這個類需要實現序列化接口: class User implements Serializable. 或者,對象保存之前就序列化為json字符串之類的。
RedisTemplate 模板
RedisUtil 模板
用來封裝RedisTemplate原始的,但是用起來復雜的API。封裝層略微簡單些的函數。
(截圖未包含所有的封裝API,因為太多了)
參考文章
作者:大寬寬
鏈接:https://www.zhihu.com/question/277363840/answer/392945240
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。