RedisTemplate使用的是 JdkSerializationRedisSerializer 序列化對象
StringRedisTemplate使用的是 StringRedisSerializer 序列化String
那有沒有辦法,能夠序列化對象,可讀性又強呢?java
spring-data-redis提供以下幾種選擇:redis
@Test public void testSerial(){ UserPO userPO = new UserPO(1111L,"小明_testRedis1",25); List<Object> list = new ArrayList<>(); for(int i=0;i<200;i++){ list.add(userPO); } JdkSerializationRedisSerializer j = new JdkSerializationRedisSerializer(); GenericJackson2JsonRedisSerializer g = new GenericJackson2JsonRedisSerializer(); Jackson2JsonRedisSerializer j2 = new Jackson2JsonRedisSerializer(List.class); Long j_s_start = System.currentTimeMillis(); byte[] bytesJ = j.serialize(list); System.out.println("JdkSerializationRedisSerializer序列化時間:"+(System.currentTimeMillis()-j_s_start) + "ms,序列化後的長度:" + bytesJ.length); Long j_d_start = System.currentTimeMillis(); j.deserialize(bytesJ); System.out.println("JdkSerializationRedisSerializer反序列化時間:"+(System.currentTimeMillis()-j_d_start)); Long g_s_start = System.currentTimeMillis(); byte[] bytesG = g.serialize(list); System.out.println("GenericJackson2JsonRedisSerializer序列化時間:"+(System.currentTimeMillis()-g_s_start) + "ms,序列化後的長度:" + bytesG.length); Long g_d_start = System.currentTimeMillis(); g.deserialize(bytesG); System.out.println("GenericJackson2JsonRedisSerializer反序列化時間:"+(System.currentTimeMillis()-g_d_start)); Long j2_s_start = System.currentTimeMillis(); byte[] bytesJ2 = j2.serialize(list); System.out.println("Jackson2JsonRedisSerializer序列化時間:"+(System.currentTimeMillis()-j2_s_start) + "ms,序列化後的長度:" + bytesJ2.length); Long j2_d_start = System.currentTimeMillis(); j2.deserialize(bytesJ2); System.out.println("Jackson2JsonRedisSerializer反序列化時間:"+(System.currentTimeMillis()-j2_d_start)); }
結果:spring
JdkSerializationRedisSerializer序列化時間:8ms,序列化後的長度:1325
JdkSerializationRedisSerializer反序列化時間:4
GenericJackson2JsonRedisSerializer序列化時間:52ms,序列化後的長度:17425
GenericJackson2JsonRedisSerializer反序列化時間:60
Jackson2JsonRedisSerializer序列化時間:4ms,序列化後的長度:9801
Jackson2JsonRedisSerializer反序列化時間:4數據庫
package com.example.demo.config.redisConfig; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Bean(name = "redisTemplate") public RedisTemplate<String, Object> getRedisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>(); redisTemplate.setConnectionFactory(factory); redisTemplate.setKeySerializer(new StringRedisSerializer()); // key的序列化類型 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // value的序列化類型 return redisTemplate; } }
注: new Jackson2JsonRedisSerializer(Object.class)須要指明類型,例如:new Jackson2JsonRedisSerializer(User.class),不然會報錯:
json
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.example.demo.bean.User。數組
或者開啓默認類型:app
ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
這種方式存儲時會自動帶上類的全路徑,佔用部分空間:性能
@Configuration public class RedisConfig { @Bean(name = "redisTemplate") public RedisTemplate<String, Object> getRedisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>(); redisTemplate.setConnectionFactory(factory); redisTemplate.setKeySerializer(new StringRedisSerializer()); // key的序列化類型 redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); // value的序列化類型 return redisTemplate; } }
注:該方式,對象須要實現接口:Serializable測試
@RunWith(SpringRunner.class) @SpringBootTest @WebAppConfiguration public class RedisTest { @Resource private RedisTemplate redisTemplate; @Test public void testRedis1(){ User user = new User(); user.setAge(11); user.setName("我是小王1"); redisTemplate.opsForValue().set("user37",user); System.out.println(redisTemplate.getValueSerializer()); System.out.println(redisTemplate.getKeySerializer()); User result = (User) redisTemplate.opsForValue().get("user37"); System.out.println(result); } }