springboot系列——redisTemplate和stringRedisTemplate对比、redisTemplate几种序列化方式比较
文章目錄
- 一、redisTemplate和stringRedisTemplate對(duì)比
- 1、StringRedisTemplate
- 2、RedisTemplate
- 二、redisTemplate序列化方式比較
- 1、性能測(cè)試對(duì)比
- 2、性能總結(jié)
- 3、方案一、考慮效率和可讀性,犧牲部分空間
- 4、方案二、空間敏感,忽略可讀性和效率影響
- 5、使用示例
- SpringBoot中RedisTemplate更改序列化方式
一、redisTemplate和stringRedisTemplate對(duì)比
RedisTemplate看這個(gè)類的名字后綴是Template,如果了解過Spring如何連接關(guān)系型數(shù)據(jù)庫的,大概不會(huì)難猜出這個(gè)類是做什么的 ,它跟JdbcTemplate一樣封裝了對(duì)Redis的一些常用的操作,當(dāng)然StringRedisTemplate跟RedisTemplate功能類似那么肯定就會(huì)有人問,為什么會(huì)需要兩個(gè)Template呢,一個(gè)不就夠了嗎?其實(shí)他們兩者之間的區(qū)別主要在于他們使用的序列化類。
RedisTemplate使用的是 JdkSerializationRedisSerializer 序列化對(duì)象 StringRedisTemplate使用的是 StringRedisSerializer 序列化String1、StringRedisTemplate
- 主要用來存儲(chǔ)字符串,StringRedisSerializer的泛型指定的是String。當(dāng)存入對(duì)象時(shí),會(huì)報(bào)錯(cuò) :can not cast into String。
- 可見性強(qiáng),更易維護(hù)。如果過都是字符串存儲(chǔ)可考慮用StringRedisTemplate。
2、RedisTemplate
- 可以用來存儲(chǔ)對(duì)象,但是要實(shí)現(xiàn)Serializable接口。
- 以二進(jìn)制數(shù)組方式存儲(chǔ),內(nèi)容沒有可讀性。
二、redisTemplate序列化方式比較
那有沒有辦法,可以序列化對(duì)象,可讀性又強(qiáng)呢?
- 1、手動(dòng)轉(zhuǎn)化成json串再存儲(chǔ)。取出數(shù)據(jù)需要反序列化。
- 2、使用其他序列化方式。
spring-data-redis提供如下幾種選擇:
- GenericToStringSerializer: 可以將任何對(duì)象泛化為字符串并序列化
- Jackson2JsonRedisSerializer: 跟JacksonJsonRedisSerializer實(shí)際上是一樣的
- JacksonJsonRedisSerializer: 序列化object對(duì)象為json字符串
- JdkSerializationRedisSerializer: 序列化java對(duì)象
- StringRedisSerializer: 簡(jiǎn)單的字符串序列化
1、性能測(cè)試對(duì)比
@Testpublic 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序列化時(shí)間:"+(System.currentTimeMillis()-j_s_start) + "ms,序列化后的長(zhǎng)度:" + bytesJ.length);Long j_d_start = System.currentTimeMillis();j.deserialize(bytesJ);System.out.println("JdkSerializationRedisSerializer反序列化時(shí)間:"+(System.currentTimeMillis()-j_d_start));Long g_s_start = System.currentTimeMillis();byte[] bytesG = g.serialize(list);System.out.println("GenericJackson2JsonRedisSerializer序列化時(shí)間:"+(System.currentTimeMillis()-g_s_start) + "ms,序列化后的長(zhǎng)度:" + bytesG.length);Long g_d_start = System.currentTimeMillis();g.deserialize(bytesG);System.out.println("GenericJackson2JsonRedisSerializer反序列化時(shí)間:"+(System.currentTimeMillis()-g_d_start));Long j2_s_start = System.currentTimeMillis();byte[] bytesJ2 = j2.serialize(list);System.out.println("Jackson2JsonRedisSerializer序列化時(shí)間:"+(System.currentTimeMillis()-j2_s_start) + "ms,序列化后的長(zhǎng)度:" + bytesJ2.length);Long j2_d_start = System.currentTimeMillis();j2.deserialize(bytesJ2);System.out.println("Jackson2JsonRedisSerializer反序列化時(shí)間:"+(System.currentTimeMillis()-j2_d_start));}結(jié)果:
JdkSerializationRedisSerializer序列化時(shí)間:8ms,序列化后的長(zhǎng)度:1325 JdkSerializationRedisSerializer反序列化時(shí)間:4 GenericJackson2JsonRedisSerializer序列化時(shí)間:52ms,序列化后的長(zhǎng)度:17425 GenericJackson2JsonRedisSerializer反序列化時(shí)間:60 Jackson2JsonRedisSerializer序列化時(shí)間:4ms,序列化后的長(zhǎng)度:9801 Jackson2JsonRedisSerializer反序列化時(shí)間:42、性能總結(jié)
- JdkSerializationRedisSerializer序列化后長(zhǎng)度最小,Jackson2JsonRedisSerializer效率最高。
- 如果綜合考慮效率和可讀性,犧牲部分空間,推薦key使用StringRedisSerializer,保持的key簡(jiǎn)明易讀;value可以使用Jackson2JsonRedisSerializer
- 如果空間比較敏感,效率要求不高,推薦key使用StringRedisSerializer,保持的key簡(jiǎn)明易讀;value可以使用JdkSerializationRedisSerializer
3、方案一、考慮效率和可讀性,犧牲部分空間
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),否則會(huì)報(bào)錯(cuò):
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.example.demo.bean.User。
或者開啟默認(rèn)類型:
ObjectMapper objectMapper = new ObjectMapper();objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);這種方式存儲(chǔ)時(shí)會(huì)自動(dòng)帶上類的全路徑,占用部分空間:
4、方案二、空間敏感,忽略可讀性和效率影響
@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;} }[](javascript:void(0)😉
注:該方式,對(duì)象需要實(shí)現(xiàn)接口:Serializable
5、使用示例
@RunWith(SpringRunner.class) @SpringBootTest @WebAppConfiguration public class RedisTest {@Resourceprivate RedisTemplate redisTemplate;@Testpublic 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);} }SpringBoot中RedisTemplate更改序列化方式
可以通過手動(dòng)配置, 將RedisTemplate的序列化方式進(jìn)行更改
package com.wenbronk.data.redis;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; 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;@SpringBootApplication public class RedisApplication {public static void main(String[] args) {SpringApplication.run(RedisApplication.class, args);}/*** redisTemplate 序列化使用的jdkSerializeable, 存儲(chǔ)二進(jìn)制字節(jié)碼, 所以自定義序列化類* @param redisConnectionFactory* @return*/@Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);// 使用Jackson2JsonRedisSerialize 替換默認(rèn)序列化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);// 設(shè)置value的序列化規(guī)則和 key的序列化規(guī)則redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.afterPropertiesSet();return redisTemplate;} }總結(jié)
以上是生活随笔為你收集整理的springboot系列——redisTemplate和stringRedisTemplate对比、redisTemplate几种序列化方式比较的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 端计算(4)-kotlin(2)
- 下一篇: SpringBoot 异常回滚 事务的使