【Redis】RedisTemplate和StringRedisTemplate的区别
两者的关系是 StringRedisTemplate 继承 RedisTemplate 。
两者的数据是不共通的:也就是说 StringRedisTemplate 只能管理 StringRedisTemplate 里面的数据,RedisTemplate 只能管理 RedisTemplate 中的数据。
RedisTemplate 看这个类的名字后缀是 Template ,如果了解过 Spring 如何连接关系型数据库的,大概不会难猜出这个类是做什么的 ,它跟 JdbcTemplate 一样封装了对Redis的一些常用的操作,当然 StringRedisTemplate 跟 RedisTemplate 功能类似那么肯定就会有人问,为什么会需要两个Template呢,一个不就够了吗?其实他们两者之间的区别主要在于他们使用的序列化类是不同的。
- StringRedisTemplate 的API假定所有的数据类型化都是字符类型,即key和value都是字符串类型。默认采用的是 String 的序列化策略,即 StringRedisSerializer ,保存的key和value都是采用此策略序列化保存的。
- RedisTemplate 默认采用的是JDK的序列化策略,即 JdkSerializationRedisSerializer ,保存的key和value都是采用此策略序列化保存的。
RedisTemplate 默认使用的序列类在在操作数据的时候,比如说存入数据会将数据先序列化成字节数组然后在存入 Redis 数据库,这个时候打开 Redis 查看的时候,你会看到你的数据不是以可读的形式展现的,而是以字节数组显示,类似下面:
StringRedisTemplate 默认存入的数据就是原文,因为 StringRedisTemplate 默认使用的是 String 序列化策略,使用 StringRedisTemplate 默认存入数据长这个样:
造成两者差异的原因是因为在初始化时,两者使用的序列化策略不同导致的,翻开源码可以看到,如下:
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {private boolean enableTransactionSupport = false;private boolean exposeConnection = false;private boolean initialized = false;private boolean enableDefaultSerializer = true;@Nullableprivate RedisSerializer<?> defaultSerializer;@Nullableprivate RedisSerializer keySerializer = null;@Nullableprivate RedisSerializer valueSerializer = null;@Nullableprivate RedisSerializer hashKeySerializer = null;@Nullableprivate RedisSerializer hashValueSerializer = null;// 其它字段略...public RedisTemplate() {}// 该方法是重写RedisAccessor的方法 RedisAccessor实现了spring的InitializingBean 也就是在启动时会执行该方法 可以看到该方法默认的序列化为JdkSerializationRedisSerializerpublic void afterPropertiesSet() {super.afterPropertiesSet();boolean defaultUsed = false;if (this.defaultSerializer == null) {this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());}if (this.enableDefaultSerializer) {if (this.keySerializer == null) {this.keySerializer = this.defaultSerializer;defaultUsed = true;}if (this.valueSerializer == null) {this.valueSerializer = this.defaultSerializer;defaultUsed = true;}if (this.hashKeySerializer == null) {this.hashKeySerializer = this.defaultSerializer;defaultUsed = true;}if (this.hashValueSerializer == null) {this.hashValueSerializer = this.defaultSerializer;defaultUsed = true;}}if (this.enableDefaultSerializer && defaultUsed) {Assert.notNull(this.defaultSerializer, "default serializer null and not all serializers initialized");}if (this.scriptExecutor == null) {this.scriptExecutor = new DefaultScriptExecutor(this);}this.initialized = true;}// 其余方法略...
}
可以看到 RedisTemplate 在初始化时是无参构造,通过 Spring 的 Bean 加载机制在项目启动时执行afterPropertiesSet来完成序列化设置,如果需要自定义序列化配置,可以自己写一个 RedisTemplate 的Bean,来完成配置。
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String,Object> redisTemplate(@Autowired RedisConnectionFactory redisConnectionFactory) {// 创建RedisTemplateRedisTemplate<String,Object> redisTemplate = new RedisTemplate<String,Object>();// 字符串和JDK序列化器RedisSerializer<String> strSerializer = RedisSerializer.string();RedisSerializer<Object> jdkSerializer = RedisSerializer.java();// 设置键值序列化器redisTemplate.setKeySerializer(strSerializer);redisTemplate.setValueSerializer(jdkSerializer);// 设置哈希字段和值序列化器redisTemplate.setHashKeySerializer(strSerializer);redisTemplate.setHashValueSerializer(jdkSerializer);// 给redisTemplate设置连接工厂redisTemplate.setConnectionFactory(redisConnectionFactory);return redisTemplate;}
}
StringRedisTemplate 就比较简单了,直接继承了 RedisTemplate,在初始化时默认使用了 String 序列化,源码如下:
public class StringRedisTemplate extends RedisTemplate<String, String> {public StringRedisTemplate() {this.setKeySerializer(RedisSerializer.string());this.setValueSerializer(RedisSerializer.string());this.setHashKeySerializer(RedisSerializer.string());this.setHashValueSerializer(RedisSerializer.string());}// 其他方法略...
}
那么就可以得出一个结论,如果你想使用默认的配置来操作 Redis,则如果操作的数据是字节数组,就是用RedisTemplate,如果操作的数据是明文,使用 StringRedisTemplate。
当然在项目中真实使用时,一般是自定义 RedisTemplate 的 Bean 实例,来设置具体的序列化策略,说白了就是 RedisTemplate 通过自定义 Bean 可以实现和 StringRedisTemplate 一样的序列化,使用起来更加灵活。
相关文章:
【Redis】RedisTemplate和StringRedisTemplate的区别
两者的关系是 StringRedisTemplate 继承 RedisTemplate 。 两者的数据是不共通的:也就是说 StringRedisTemplate 只能管理 StringRedisTemplate 里面的数据,RedisTemplate 只能管理 RedisTemplate 中的数据。 RedisTemplate 看这个类的名字后缀是 Temp…...
面试经典150题(101-104)
leetcode 150道题 计划花两个月时候刷完之未完成后转,今天(第1天)完成了4道(101-104)150: 101.(215. 数组中的第K个最大元素) 题目描述: 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请…...
Java实现读取转码写入ES构建检索PDF等文档全栈流程
背景 之前已简单使用ES及Kibana和在线转Base64工具实现了检索文档的demo,并已实现WebHook的搭建和触发流程接口。 传送门: 基于GitBucket的Hook构建ES检索PDF等文档全栈方案 使用ES检索PDF、word等文档快速开始 实现读取本地文件入库ES 总体思路&…...
主流开发环境和开发语言介绍
主流开发环境和开发语言介绍 一、主流开发环境介绍 主流开发环境是指广泛应用于软件开发的集成开发环境(Integrated Development Environment,简称IDE)。IDE是一种集成了编辑器、编译器、调试器等工具的软件,提供了一站式的开发环…...
C++ 使用 nlohmann::json存储json文件
C 使用 nlohmann::json存储json文件 nlohmann::json 概述JSON 存储的示例以追加的方式存储json文件 nlohmann::json 概述 nlohmann::json 是 C 中一个流行的 JSON 库,由 Niels Lohmann 开发。它提供了一个简单而强大的 API,用于解析、构建、操作和序列化…...
何为OOM(Out of Memory)?
OOM(Out of Memory) 是指程序运行过程中内存不足的情况。在 Spark 应用程序中,OOM 是一个非常常见的问题,尤其是在处理大规模数据集或执行资源密集型的操作时。当 Spark 作业尝试使用的内存超过了为其分配的内存限制时,…...
SpringBoot+Mybatis-plus+shardingsphere实现分库分表
SpringBootMybatis-plusshardingsphere实现分库分表 文章目录 SpringBootMybatis-plusshardingsphere实现分库分表介绍引入依赖yaml配置DDL准备数据库ds0数据库ds1 entitycotrollerserviceMapper启动类测试添加修改查询删除 总结 介绍 实现亿级数据量分库分表的项目是一个挑战…...
FPGA DDR3简介及时序
一,DDR3基础知识 1、DDR3全称第三代双倍速率同步动态随机存储器。 特点:①掉电无法保存数据,需要周期性的刷新。 ②时钟上升沿和下降沿都会传输数据。 ③突发传输,突发长度Burst Length一般为8 2、DDR3的存储: bank、行地址和列地址 数据怎么存入到D…...
java网络编程 02 socket
01.socket定义 02.TCP编程 import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket;public class clientSocket {public static void main(String[] args) throws IOException {Socket socket new Socket(Ine…...
【Web安全】SQL各类注入与绕过
【Web安全】SQL各类注入与绕过 【Web安全靶场】sqli-labs-master 1-20 BASIC-Injection 【Web安全靶场】sqli-labs-master 21-37 Advanced-Injection 【Web安全靶场】sqli-labs-master 38-53 Stacked-Injections 【Web安全靶场】sqli-labs-master 54-65 Challenges 与62关二…...
C++ 设计模式
文章目录 类图泛化实现关联聚合组合依赖总结 类内部的三种权限(公有、保护、私有)类的三种继承方式描述与图总结 面向对象七大原则单一职责原则(Single Responsibility Principle)里氏替换原则(Liskov Substitution Pr…...
安卓使用ExoPlayer出现膨胀类异常
1.导包 implementation com.google.android.exoplayer:exoplayer-core:2.15.1implementation com.google.android.exoplayer:exoplayer-ui:2.15.1 2.在Androidifest.xml加入权限,我这里加了网络与读写权限 <uses-permission android:name"android.permissio…...
C++之析构函数
在 C 中,析构函数(Destructor)是一个特殊的成员函数,用于在对象生命周期结束时执行清理工作和资源释放。析构函数的名称与类名相同,前面加上波浪号(~),不接受任何参数,也…...
108. 将有序数组转换为二叉搜索树【简单】
108. 将有序数组转换为二叉搜索树【简单】 题目描述: 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉…...
vue3中watch和watchEffect的区别!!!
vue3中watch和watchEffect的区别!!! 在 Vue 3 中,watch 和 watchEffect 都是监听器,但在写法和使用上有所区别。让我们来详细了解一下它们之间的不同: watch: watch 具有一定的惰性(lazy&#…...
【JavaEE初阶 -- 计算机核心工作机制】
这里写目录标题 1.冯诺依曼体系2.CPU是怎么构成的3.指令表4.CPU执行代码的方式5.CPU小结:6.编程语言和操作系统7. 进程/任务(Process/Task)8.进程在系统中是如何管理的9. CPU分配 -- 进程调度10.内存分配 -- 内存管理11.进程间通信 1.冯诺依曼…...
springcloud:3.6测试信号量隔离
服务提供者【test-provider8001】 Openfeign远程调用服务提供者搭建 文章地址http://t.csdnimg.cn/06iz8 相关接口 测试远程调用:http://localhost:8001/payment/index 服务消费者【test-consumer-resilience4j8004】 Openfeign远程调用消费者搭建 文章地址http://t…...
AI化未来:智能科技的新纪元
AI化未来:智能科技的新纪元 我们正处在一个前所未有的科技革新时期,人工智能(AI)的发展正日益渗透到我们生活的方方面面,预示着AI化未来的到来。这是一场前所未有的科技革命,其深度和广度超越了历史上的任…...
Unity 整体界面淡入淡出效果
在Unity中,如果我们要实现控制多个组件同时淡出,同时淡入的效果,可以使用DOTween插件实现。 如图,一个页面中带有背景,一张图片,一个文本,一个滑动条。 要实现以上界面的整体淡入淡出ÿ…...
反序列化逃逸 [安洵杯 2019]easy_serialize_php1
打开题目 题目源码: <?php$function $_GET[f];function filter($img){$filter_arr array(php,flag,php5,php4,fl1g);$filter /.implode(|,$filter_arr)./i;return preg_replace($filter,,$img); }if($_SESSION){unset($_SESSION); }$_SESSION["user&qu…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
前端调试HTTP状态码
1xx(信息类状态码) 这类状态码表示临时响应,需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分,客户端应继续发送剩余部分。 2xx(成功类状态码) 表示请求已成功被服务器接收、理解并处…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...
麒麟系统使用-进行.NET开发
文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的,如果需要进行.NET开发,则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET,所以要进…...

