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 ...
随机推荐
- Python进制表示及转换
进制表示: 二进制:>>> abin = 0b1000>>> abin8 八进制:>>> aoct = 0o123 (数字0,字母o)>&g ...
- 面试 -- Http协议相关(转载)
http请求由三部分组成,分别是:请求行.消息报头.请求正文 HTTP(超文本传输协议)是一个基于请求与响应模式的.无状态的.应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接 ...
- Elasticsearch 基础知识要点与性能监控
本文的来源是我翻译国外的一篇技术博客,感谢原作者Emily Chang,原文地址通过如下的知识,我们能大致学到关于ES的一些基本知识,进而对elasticsearch的性能进行监控和调优 注意elas ...
- java反射出字段信息和值
/** * */ package test; import java.lang.reflect.Field; import java.lang.reflect.Modifier; /** * @aut ...
- Raspbian首次安装后无法使用SSH链接
使用Putty连接树莓派,出现Network Error:Connection Refused 新版的Raspbian系统默认禁用了SSH. 解决方法:在/boot分区创建名为"ssh&qu ...
- mysql存储过程变量的拼接
存储过程变量的拼接 有时候我们需要模糊查询,但是同时我们又要 在模糊查询的时候使用变量,我们又想在变量的后面拼接一个%去匹配模糊查询 那么就会用到 concat函数 示例如下: www. ...
- ModuleNotFoundError: No module named 'Crypto.Cipher'
ModuleNotFoundError: No module named 'Crypto.Cipher'报错问题 原因及处理: 在使用python3是经常会用到import一个第三方库,但是有时候会提 ...
- java 中自定义类的概述
作业: 描述商品类 Goods 4个属性 商品名字 大小 价格 库存 把商品类放进集合中 小米品牌 大小 价格 库存的数量 都存集合 华为..... 魅族 public class Goods{ St ...
- Apache Solr 初级教程(介绍、安装部署、Java接口、中文分词)
Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...
- 20190311 Windows安装ZooKeeper
1. 说明 记录过程中踩过的坑 1.1. 环境 本机环境:Win10 ZooKeeper版本:3.4.6 2. 安装 2.1. 下载 官网下载网址 2.2. 修改配置文件 复制conf目录下的zoo_ ...