SpringDataRedis的序列化的一些問題 RedisTemplate可以接收任意Object作為值寫入Redis,但是如果不實現設置序列化器的化預設是採用JDK序列化,序列化後的結果可讀性差並且記憶體占用空間大,如下圖。 自定義RedisTemplate的序列化方式 key和 hashKey採 ...
SpringDataRedis的序列化的一些問題
RedisTemplate可以接收任意Object作為值寫入Redis,但是如果不實現設置序列化器的化預設是採用JDK序列化,序列化後的結果可讀性差並且記憶體占用空間大,如下圖。
自定義RedisTemplate的序列化方式
key和 hashKey採用 string序列化,value和HashValue採用JSON序列化
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){
//創建RedisTemplate對象
RedisTemplate<String, Object> template = new RedisTemplate<>();
//設置連接工廠
template.setConnectionFactory(connectionFactory);
//創建JSON序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//設置key和HashKey的序列化
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
//設置value和HashValue的序列化
template.setValueSerializer(jsonRedisSerializer);
template.setHashValueSerializer(jsonRedisSerializer);
//返回
return template;
}
}
但是JSON序列化仍存在著一些問題。為了在反序列化時知道對象的類型,JSON序列化器會將類的class類型寫入json結果中,存入Redis,會帶來額外的記憶體開銷,如下圖所示。
手動序列化,節省Redis記憶體開銷
為了節省記憶體空間,我們不使用JSON序列化器來處理value,而使用String序列化器,要求只能存儲String類型的key和value。當需要存儲Java對象時,手動完成對象的序列化和反序列化。
Spring提供了StringRedisTemplate類,它的key和value的序列化方式預設就是String方式。
class RedisStringTests {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
void testSaveUser() throws JsonProcessingException {
//創建對象
User user = new User("虎哥", 21);
//手動序列化
String json = mapper.writeValueAsString(user);
//寫入數據
stringRedisTemplate.opsForValue().set("user:200", json);
//獲取數據
String jsonUser = stringRedisTemplate.opsForValue().get("user:200");
//手動反序列化
User user1 = mapper.readValue(jsonUser, User.class);
System.out.println("user1 = " + user1);
}
}
結果如下: