前言
上一篇文章講的搭建一個redis+ spring boot 的實例,用到了RedisTemplate,可以成功的訪問redis數據庫,也可以從中讀取數據並顯示在頁面上,但是呢有瑕疵,那就是其實存在數據庫中的Key值是亂碼的,類似下面圖片這樣的。在網上找了一堆的解決辦法,看到有StringRedisTemplate 代替RedisTemlate的,所以這邊文章就來說說二者到底有什麼不同,兩者有哪些與缺點,以及在項目中我們如何去使用它。
二者不同
先來看看StringRedisTemplate ,爲什麼先看他,因爲它實際上是繼承RedisTemplate的,並且源碼很簡單,只有十幾行,所以先來看看它。
源碼:
public class StringRedisTemplate extends RedisTemplate<String, String> {
public StringRedisTemplate() {
this.setKeySerializer(RedisSerializer.string());
this.setValueSerializer(RedisSerializer.string());
this.setHashKeySerializer(RedisSerializer.string());
this.setHashValueSerializer(RedisSerializer.string());
}
public StringRedisTemplate(RedisConnectionFactory connectionFactory) {
this();
this.setConnectionFactory(connectionFactory);
this.afterPropertiesSet();
}
protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
return new DefaultStringRedisConnection(connection);
}
}
看源碼可以看到,就兩個構造方法,構造方法中對key和value 進行序列化,這個序列化是使用RedisSerializer.string()序列化的。看看RedisSerializer.string()的源碼可以發現就是將編碼格式設置成了UTF-8
再看看帶參數的構造函數,多了一個RedisConnectionFactory 參數,這個參數是是在創建連接的時候,設置連接的信息。在網上copy了一個這個方法的實例,可以參考一下:
看到這裏,大夥差不多就應該知道StringRedisTemplate和RedisTemlate有什麼不同了吧。StringRedisTemplate繼承了RedisTemlate,但是又僅僅修改了key和values序列化的方式。那就說明StringRedisTemplate和RedisTemlate實際上就是key和values序列化的方式不同啦。
那接下來再看看RedisTemlate是怎麼序列化的。RedisTemlate的源碼就比較多了,我們這裏就暫時先看其序列化的:
可以看到redisTemplate是使用jdk默認編碼格式來序列化的。
new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader())
所以纔出現了文章最開始,使用redisTemplate,存的key值在redis數據庫中實際上是亂碼的。而StringTemplate不會。
二者優缺
關於二者優缺點,我們先來看一個例子:
還是上一篇博客的源代碼,RedisService層使用的是RedisTemplate,界面上存取,顯示都沒有問題,這裏重點關注一下,getUser(),我這裏強轉User,在界面上可以正常顯示。
@Autowired
private RedisTemplate redisTemplate;
public boolean setUser(User user){
ValueOperations ops=redisTemplate.opsForValue();
ops.set(user.getNickname(),user);
return true;
}
public User getUser(String name){
ValueOperations ops=redisTemplate.opsForValue();
return (User)ops.get(name);
}
那我們再使用StringTemplate
修改RedisService層
@Autowired
private StringRedisTemplate stringRedisTemplate;
public boolean setUser(User user){
ValueOperations ops=stringRedisTemplate.opsForValue();
ops.set(user.getNickname(),user);
return true;
}
public User getUser(String name){
ValueOperations ops=stringRedisTemplate.opsForValue();
return (User)ops.get(name);
}
再來實行set 和get 就會報錯。
啊啊啊,寫不完啦,先放放明天繼續~
大家七夕快樂嘿嘿