springboot系列十一、redisTemplate和stringRedisTemplate对比、redisTemplate几种序列化方式比较
一、redisTemplate和stringRedisTemplate对比
RedisTemplate使用的是 JdkSerializationRedisSerializer 序列化对象
StringRedisTemplate使用的是 StringRedisSerializer 序列化String
1、StringRedisTemplate
- 主要用来存储字符串,StringRedisSerializer的泛型指定的是String。当存入对象时,会报错 :can not cast into String。
- 可见性强,更易维护。如果过都是字符串存储可考虑用StringRedisTemplate。

2、RedisTemplate
- 可以用来存储对象,但是要实现Serializable接口。
- 以二进制数组方式存储,内容没有可读性。

二、redisTemplate序列化方式比较
那有没有办法,可以序列化对象,可读性又强呢?
- 1、手动转化成json串再存储。取出数据需要反序列化。
- 2、使用其他序列化方式。
spring-data-redis提供如下几种选择:
- GenericToStringSerializer: 可以将任何对象泛化为字符串并序列化
- Jackson2JsonRedisSerializer: 跟JacksonJsonRedisSerializer实际上是一样的
- JacksonJsonRedisSerializer: 序列化object对象为json字符串
- JdkSerializationRedisSerializer: 序列化java对象
- StringRedisSerializer: 简单的字符串序列化
1、性能测试对比
@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));
}
结果:
JdkSerializationRedisSerializer序列化时间:8ms,序列化后的长度:1325
JdkSerializationRedisSerializer反序列化时间:4
GenericJackson2JsonRedisSerializer序列化时间:52ms,序列化后的长度:17425
GenericJackson2JsonRedisSerializer反序列化时间:60
Jackson2JsonRedisSerializer序列化时间:4ms,序列化后的长度:9801
Jackson2JsonRedisSerializer反序列化时间:4
2、性能总结
- JdkSerializationRedisSerializer序列化后长度最小,Jackson2JsonRedisSerializer效率最高。
- 如果综合考虑效率和可读性,牺牲部分空间,推荐key使用StringRedisSerializer,保持的key简明易读;value可以使用Jackson2JsonRedisSerializer
- 如果空间比较敏感,效率要求不高,推荐key使用StringRedisSerializer,保持的key简明易读;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),否则会报错:
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.example.demo.bean.User。
或者开启默认类型:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
这种方式存储时会自动带上类的全路径,占用部分空间:

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;
}
}
注:该方式,对象需要实现接口:Serializable
5、使用示例
@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);
}
}
springboot系列十一、redisTemplate和stringRedisTemplate对比、redisTemplate几种序列化方式比较的更多相关文章
- SpringBoot 系列教程之事务不生效的几种 case
SpringBoot 系列教程之事务不生效的几种 case 前面几篇博文介绍了声明式事务@Transactional的使用姿势,只知道正确的使用姿势可能还不够,还得知道什么场景下不生效,避免采坑.本文 ...
- SpringBoot系列教程web篇Servlet 注册的四种姿势
原文: 191122-SpringBoot系列教程web篇Servlet 注册的四种姿势 前面介绍了 java web 三要素中 filter 的使用指南与常见的易错事项,接下来我们来看一下 Serv ...
- SQL Server调优系列基础篇(常用运算符总结——三种物理连接方式剖析)
前言 上一篇我们介绍了如何查看查询计划,本篇将介绍在我们查看的查询计划时的分析技巧,以及几种我们常用的运算符优化技巧,同样侧重基础知识的掌握. 通过本篇可以了解我们平常所写的T-SQL语句,在SQL ...
- python笔记-20 django进阶 (model与form、modelform对比,三种ajax方式的对比,随机验证码,kindeditor)
一.model深入 1.model的功能 1.1 创建数据库表 1.2 操作数据库表 1.3 数据库的增删改查操作 2.创建数据库表的单表操作 2.1 定义表对象 class xxx(models.M ...
- SpringBoot系列十一:SpringBoot整合Restful架构(使用 RestTemplate 模版实现 Rest 服务调用、Swagger 集成、动态修改日志级别)
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot整合Restful架构 2.背景 Spring 与 Restful 整合才是微架构的核心,虽然在整 ...
- springBoot启动时让方法自动执行的几种实现方式
一.开篇名义 在springBoot中我们有时候需要让项目在启动时提前加载相应的数据或者执行某个方法,那么实现提前加载的方式有哪些呢?接下来我带领大家逐个解答 1.实现ServletContextAw ...
- STM32 HAL库学习系列第3篇 常使用的几种延时方式
1 自带的hal_delay 函数 毫秒级延迟 void HAL_Delay(__IO uint32_t Delay) { uint32_t tickstart = HAL_GetTick( ...
- SpringBoot系列之集成Dubbo的方式
SpringBoot系列之集成Dubbo的方式 本博客介绍Springboot框架集成Dubbo实现微服务的3种常用方式,对于Dubbo知识不是很熟悉的,请先学习我上一篇博客:SpringBoot系列 ...
- .net 各种序列化方式效率对比
在服务与服务之间传输的是二进制数据,而在此之前有多种方法将数据内容进行序列化来减小数据传递大小,现针对于目前主流的几种序列化方式做了简单数据统计对比. 先做下简单介绍↓↓↓ 1.protobuf-ne ...
随机推荐
- A1032. Sharing
To store English words, one method is to use linked lists and store a word letter by letter. To save ...
- A1059. Prime Factors
Given any positive integer N, you are supposed to find all of its prime factors, and write them in t ...
- NOIP 普及组 2014 比例简化
传送门 https://www.cnblogs.com/violet-acmer/p/9898636.html 题解: 一开始想多了,以为得保证两者之间的相对比率,至少不能改变的太离谱啊. but,直 ...
- BAPC2017
Benelux Algorithm Programming Contest 2017 参考资料: https://blog.csdn.net/sizaif/article/details/798586 ...
- C# 同步工作站与SQL服务器的时间
/// <summary> /// 设置本机时间 /// </summary> public class LocalTimeSync { [DllImport("Ke ...
- P4315 月下“毛景树”
P4315 月下"毛景树" 题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬 ...
- CentOS Linux release 7.3破解密码详解
CentOS Linux release 7.3破解密码详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 公司最近接了一个项目,拿到客户现有的源代码,但是服务器用户密码并不知情, ...
- JAVA记录-maven JDK配置和常用操作
1.pom.xml加入(JDK编译器配置) <build> <finalName>项目名</finalName> <plugins> <plugi ...
- Elasticsearch之中文分词器插件es-ik的自定义词库
它在哪里呢? 非常重要! [hadoop@HadoopMaster custom]$ pwd/home/hadoop/app/elasticsearch-2.4.3/plugins/ik/config ...
- 【1】存在大于1s的FullGC
目前有存在大于1s的FullGC,金桥的机器目前是2C4G的,使用的GC方法只能使用单线程进行串行的回收,导致GC比较慢. 建议可以调整GC参数,改用CMS,能够解决这个问题, 参数修改方法: 在应用 ...