【redis】fastjson 中的 FastJsonRedisSerializer 學習

FastJsonRedisSerializer 對 Java Object 寫入和讀取redis的操作支持

場景

開始學習redis

剛開始學習的時候用的是 redis 的 RedisTemplate,這個比較好上手:

@Autowired private RedisTemplate redisTemplate;

ValueOperations<String, String> vo = redisTemplate.opsForValue();
vo.set("mykey", "this is a value");//存到redis

這是一個 Stirng 的 key ,存了一個 String 的 value。當時我在做一個單點登錄系統,想要存入的 value 是一個 Java Object,這時遇到了一個問題,就是怎麼通過這個進行 Java Object 的寫入和讀取。

問題出現

寫入的時候很簡單,就是將 Java Object 進行 toString() 方法的重寫,然後就可以以 String 的方式寫入 redis ,但是讀取的時候出現了一個麻煩的問題,我是用 Java 默認生成的 toString() 重寫方法,出來的是這個格式:

SessionUser{id='1', token='c6f91e444dd3e7ab91541394bc5aa5f8', createTime=1529374760832, lastLoginTime=1529374941717}

因爲後續的操作是要用到 Java Object,所以這個字符串讀取出來要還原成 Java Object 是一個很頭痛的問題,默認方法生成的字符串不是 json 格式,所以不可以通過 json解析獲取對象,如果將自己定一個 json 生成的 toString() 方法,工作量大而且對 model 的修改不是很好,萬一後面 model 因爲數據庫表的修改而重新生成,那麼 model 又要再來一遍修改。

解決方法

在閱讀資料的時候,方向有一個解決方法是用一個序列化工具類來解決,核心思想是用原生的 Jedis 來操作,同時寫入的 key 和 value 都是 byte[] 類型。這時在 fastjson 包中找到了一個支持序列化和反序列化的類 FastJsonRedisSerializer 。
寫入和讀取的使用很簡單,

寫入:

FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(SessionUser.class);
jedis.set(user.getId().getBytes(), fastJsonRedisSerializer.serialize(sessionUser));

讀取:

FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(SessionUser.class);
SessionUser sessionUser = (SessionUser) fastJsonRedisSerializer.deserialize(vo.get(userId).getBytes());

這是最直接的使用方法,可以通過封裝成工具類來使用。

public static byte[] getByteArrFromObj(Object obj, Class clazz) {
        FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(clazz);
        return fastJsonRedisSerializer.serialize(obj);
}

public static Object getObjFromByteArr(byte[] byteArr, Class clazz) {
    FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(clazz);
    return fastJsonRedisSerializer.deserialize(byteArr);
}

PS

Java 自帶的序列化和反序列化據說效率不行,佔用空間也大,故不做推薦。

序列化

Object obj = new Object();//準備序列化的 object
ByteArrayOutputStream baos = new ByteArrayOutputStream();  
ObjectOutputStream oos = new ObjectOutputStream(baos);  
oos.writeObject(object);  
byte[] bytes = baos.toByteArray();  
return bytes;  

反序列化

ByteArrayInputStream bais = new ByteArrayInputStream(bytes);  
ObjectInputStream ois = new ObjectInputStream(bais);  
return ois.readObject();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章