03. SpringBoot 整合 Redis
文章目录
- Jedis
- 导入依赖
- 测试连接
- Jedis 实现事务
- SpringBoot 整合 Redis
- RedisTemplate
- SpringBoot 整合 Redis 测试
- RedisTemplate 序列化
- RedisUtils
Jedis
Jedis 是 Redis 官方推荐的 Java 连接工具。
导入依赖
</dependencies><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency></dependencies>
测试连接
package com.zk.jedis;import redis.clients.jedis.Jedis;public class TestJedis {public static void main(String[] args) {Jedis jedis = new Jedis("127.0.0.1", 6379);System.out.println(jedis.ping());}
}
输出:
PONG
Jedis 实现事务
执行成功:
package com.zk.jedis;import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;public class TestJedis {public static void main(String[] args) {Jedis jedis = new Jedis("127.0.0.1", 6379);JSONObject jsonObject = new JSONObject();jsonObject.put("name", "xiaoming");jsonObject.put("num", "24");String result = jsonObject.toJSONString();// 开启事务Transaction multi = jedis.multi();try{multi.set("user1", result);multi.set("user2", result);// 执行事务multi.exec();}catch (Exception e){// 失败就放弃事务multi.discard();}finally {// 关闭事务multi.close();}System.out.println(jedis.get("user1"));System.out.println(jedis.get("user2"));}
}
输出:
{"num":"24","name":"xiaoming"}
{"num":"24","name":"xiaoming"}
执行失败:
package com.zk.jedis;import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;public class TestJedis {public static void main(String[] args) {Jedis jedis = new Jedis("127.0.0.1", 6379);jedis.flushDB();JSONObject jsonObject = new JSONObject();jsonObject.put("name", "xiaoming");jsonObject.put("num", "24");String result = jsonObject.toJSONString();// 开启事务Transaction multi = jedis.multi();
// jedis.watch(result);try{multi.set("user1", result);multi.set("user2", result);int i = 1 / 0; // 代码执行异常,事务会执行失败// 执行事务multi.exec();}catch (Exception e){// 失败就放弃事务multi.discard();}finally {// 关闭事务multi.close();}System.out.println(jedis.get("user1"));System.out.println(jedis.get("user2"));}
}
输出:
null
null
SpringBoot 整合 Redis
SpringBoot 操作数据:Spring Data jpa jdbc redis。
Spring Data 也是和 SpringBoot 齐名的项目。
在 SpringBoot 2.x 之后,Jedis 被换成了 Lettuce。
Jedis:底层采用直连的方式,如果多个线程操作,不安全。要避免不安全,就要使用 Jedis Pool 连接池!更像 BIO 模式!
Lettuce:采用 netty,实例可以在多个线程中共享,不存在不安全的情况!可以减少线程数,性能高,更像 NIO 模式!
SpringBoot 所有的配置类,都有一个自动配置类,RedisAutoConfiguration;
自动配置类都会绑定一个 properties 文件,RedisProperties。
RedisTemplate
- 默认的 RedisTemplate 没有过多的设置,redis 保存的对象都是需要序列化的!
- RedisTemplate<Object, Object> 的两个参数都是 Object 类型的,我们使用需要强制转换 RedisTemplate<String, Object>(我们期望使用 String 类型的 key);
- @ConditionalOnMissingBean:判断当前需要注入 Spring 容器的 bean 的实现类是否已经含有,有的话不注入,没有就注入。(可以使用默认的 RedisTemplate,也可以自定义 RedisTemplate)
SpringBoot 整合 Redis 测试
- 导入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
- 配置连接
# SpringBoot 所有的配置类,都有一个自动配置类,RedisAutoConfiguration;
# 自动配置类都会绑定一个 properties 文件,RedisProperties。# 配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
- 测试
RedisTemplate 序列化
默认的 RedisTemplate 没有过多的设置,redis 保存的对象都是需要序列化的!
@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {// 我们为了自己使用方便,一般直接使用<String, Object>RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();// 配置连接工厂redisTemplate.setConnectionFactory(connectionFactory);// Json 的序列化//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();//指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和publicom.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);jackson2JsonRedisSerializer.setObjectMapper(om);// String 的序列化StringRedisSerializer stringSerializer = new StringRedisSerializer();// key 采用 String 的序列化方式redisTemplate.setKeySerializer(stringSerializer);// Hash 的 key 也采用 String 的序列化方式redisTemplate.setHashKeySerializer(stringSerializer);// value 采用 jackson 的序列化方式redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// Hash 的 value 也采用 jackson 的序列化方式redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);redisTemplate.afterPropertiesSet();RedisUtils.setRedisTemplate(redisTemplate);return redisTemplate;}
RedisUtils
package com.zte.rdcloud.wbs.util;import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;import java.util.Collection;
import java.util.Optional;
import java.util.concurrent.TimeUnit;/*** @author 10307952* @date 2023/1/31 下午5:05*/
@Slf4j
@Component
public class RedisUtils {@Setterprivate static RedisTemplate<String, Object> redisTemplate;/*** 为键值设置过期时间,单位秒** @param key 键* @param time 时间(秒)* @return true:成功;false:失败*/public static boolean expire(String key, long time) {try {if (time > 0){redisTemplate.expire(key, time, TimeUnit.SECONDS);}return true;}catch (Exception e){log.error(e.getMessage());return false;}}//------------------------------String-----------------------------/*** 普通缓存放入** @param key 键* @param value 值* @return true成功 false失败*/public static boolean set(String key, Object value) {try {redisTemplate.opsForValue().set(key, value);return true;} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 普通缓存放入并设置过期时间** @param key 键* @param value 值* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期* @return true成功 false 失败*/public static boolean set(String key, Object value, long time) {try {if(time > 0){redisTemplate.opsForValue().set(key, value, time);}else{set(key, value);}return true;}catch (Exception e){log.error(e.getMessage());return false;}}/*** 删除缓存** @param key 可以传一个值 或多个*/public static void del(String... key) {try {if(null != key && key.length > 0){if(key.length == 1){redisTemplate.delete(key[0]);}else{redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));}}}catch(Exception e){log.error(e.getMessage());}}/*** 普通缓存获取** @param key* @return*/public static Object get(String key){try {return null == key ? null : redisTemplate.opsForValue().get(key);}catch(Exception e){log.error(e.getMessage());return null;}}/*** 获取旧值,缓存新值** @param key 键* @param value 值* @return true成功 false失败*/public static Object getAndSet(String key, Object value) {try {return redisTemplate.opsForValue().getAndSet(key, value);} catch (Exception e) {return null;}}//------------------------------Hash-----------------------------/*** 向一张hash表中放入数据,如果不存在将创建,存在则覆盖** @param key 键* @param item 项* @param value 值* @return true 成功 false失败*/public static boolean hSet(String key, String item, Object value) {try {redisTemplate.opsForHash().put(key, item, value);return true;}catch (Exception e){log.error(e.getMessage());return false;}}/*** 向一张hash表中放入数据,如果不存在将创建,存在则覆盖,并设置过期时间** @param key 键* @param item 项* @param value 值* @return true 成功 false失败*//* public static boolean hSet(String key, String item, Object value, long time) {try {redisTemplate.opsForHash().put(key, item, value);if(time > 0){expire(key, time);}return true;}catch (Exception e){log.error(e.getMessage());return false;}}*//*** 向一张hash表中放入数据,如果不存在将创建,存在则只设置失效时间(不会设置新值)** @param key 键* @param item 项* @param value 值* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间* @return true 成功 false失败*//* public static boolean hSetIfAbsent(String key, String item, Object value, long time) {try {Boolean result = redisTemplate.opsForHash().putIfAbsent(key, item, value);if (time > 0) {expire(key, time);}return result;} catch (Exception e) {log.error(e.getMessage());return false;}}*//*** 判断hash表中是否有该项的值** @param key 键 不能为null* @param item 项 不能为null* @return true 存在 false不存在*//*public static boolean hHasKey(String key, String item) {return redisTemplate.opsForHash().hasKey(key, item);}*//*** 删除hash表中的值** @param key 键 不能为null* @param item 项 可以是多个 不能为null*/public static void hDel(String key, Object... item) {try {redisTemplate.opsForHash().delete(key, item);}catch(Exception e){log.error("redis failed hdel", e);}}/*** 获取指定键对应的值** @param key 键 不能为null* @param item 项 不能为null* @return 值*/public static Object hGet(String key, String item) {try {return redisTemplate.opsForHash().get(key, item);}catch (Exception e){log.error(e.getMessage());return null;}}}
相关文章:
03. SpringBoot 整合 Redis
文章目录 Jedis导入依赖测试连接Jedis 实现事务 SpringBoot 整合 RedisRedisTemplateSpringBoot 整合 Redis 测试RedisTemplate 序列化RedisUtils Jedis Jedis 是 Redis 官方推荐的 Java 连接工具。 导入依赖 </dependencies><dependency><groupId>redis.c…...

01-Linux【准备篇】
一、学Linux的作用? 1.Linux下开发(部署)软件项目 2.Linux运维 二、Linux的强与弱 1.薄弱 个人桌面领域的应用 此领域是传统Linux应用薄弱的环节,近些年随着Ubuntu、fedora等优秀桌面环境的兴起,Linux在个人桌面领域的占有率在慢慢提高…...

在IDEA中配置servlet(maven配置完成的基础下)
在IDEA中配置servlet(maven配置完成的基础下) 1.先新建一个项目 2.选择尾巴是webapp的,名称自定义 3.点击高级设置,修改组id 点击创建,等待jar包下载完成。在pom.xml中配置以下 <dependency><groupId>ja…...

pyqt6水平布局
效果预览 main_window.ui <?xml version"1.0" encoding"UTF-8"?> <ui version"4.0"><class>MainWindow</class><widget class"QMainWindow" name"MainWindow"><property name"geo…...

CLIP论文学习
学习来自B站bryanyzhu...

手把手教大家,怎么查看抖音小店的类目保证金?
大家好,我是喷火龙。 抖音小店的类目保证金也介绍过很多次了,不同的类目有不同的保证金,要想准确的知道自己想做的类目要交多少保证金的话,还是去官网查询比较可靠。 今天,就教大家怎么去查询自己想做的类目要交多少…...

5.24作业
...

Linux之LLVM、Clang、Clang++区别及用法实例(六十五)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...
CentOS7 安装 Mysql 5.7:密码查看与修改、更改端口、开机启动
文章目录 下载 MySQL yum包安装MySQL源安装MySQL服务端,需要等待一些时间启动MySQL修改密码方式一:临时密码获取临时密码,MySQL5.7为root用户随机生成了一个密码通过临时密码登录MySQL,进行修改密码操作 方式二:skip-grant-tables…...

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(十三)
本系列课程,将重点讲解Phpsploit-Framework框架软件的基础使用! 本文章仅提供学习,切勿将其用于不法手段! 接上一篇文章内容,讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 我们,继续讲一…...
linux替换文件中的字符串
linux替换文件中的字符串 方法一:使用sed命令进行替换 sed -i s/原字符串/新字符串/g 文件名 ex: sed -i s/2024-04-25%/2024-04-26%/g sql10.sql ex:,"analyzer":"ik_analyzer" 替换为空 sed -i s/,"analyzer":"ik_analyz…...
【前端每日基础】day22——js控制结构
循环语句用于重复执行代码块。 for 循环 常用于需要精确控制循环次数的情况。 for (let i 0; i < 5; i) {console.log("Iteration:", i); }while 循环 当条件为真时重复执行代码块,适用于循环次数不确定但条件明确的情况。 let i 0;while (i <…...

npm详解
引言 在JavaScript和Node.js开发领域,npm(Node Package Manager)是一个不可或缺的工具。它不仅是一个包管理器,也是一个强大的生态系统,允许开发者共享和重用代码。本文将详细介绍npm的基本概念、主要功能以及如何有效…...

ChatGPT-4o 实战 如何快速分析混淆加密和webpack打包的源码
ChatGPT-4o 几个特点 一个对话拥有长时间的记忆,可以连续上传文件,让其分析,最大一个代码文件只能3M,超出3M的文件,可以通过split-file可以进行拆分 其次ChatGPT-4o可以生成文件的下载链接,这有利于大文件的…...

自然资源-各级国土空间总体规划的审查要点及流程总结
自然资源-各级国土空间总体规划的审查要点及流程总结 国土空间规划是对一定区域国土空间开发保护在空间和时间上作出的安排,包括总体规划、详细规划和相关专项规划。 国土空间规划管理是国土空间规划中重要的一环。中共中央、国务院发布《关于建立国土空间规划体系…...

电表远传抄表是什么?
1.电表远传抄表:简述 电表远传抄表,又称为远程控制自动抄表系统,是电力行业的智能化技术运用,它通过无线或通信网络技术,完成对电表数据信息的远程收集解决。此项技术不仅提升了抄水表高效率,降低了人工偏…...
【简明指南:Python中的异常处理与稳健代码设计】
文章目录 前言异常处理基础捕获多种异常确保资源被释放使用else子句自定义异常结论 前言 软件开发过程中,保证代码的稳健性和可靠性至关重要。异常处理是实现这一目标的关键技术之一。在Python编程中,合理地捕获和处理异常不仅能提高程序的健壮性&#…...

STM32—HAL-PWM-舵机180(每个频率对应每个角度)
1开启时钟 2开启定时器和通道设置为PWM模式 3将定时时间设置为50Hz(20ms)//每25为1ms 4代码编写 4.1开启PWM 4.2改PWM的占空比 4.3效果0~180度在0度 源码 /* USER CODE BEGIN Header */ /******************************************************************************…...

MyBatis详细教程!!(入门版)
目录 什么是MyBatis? MyBatis入门 1)创建工程 2)数据准备 3)配置数据库连接字符串 4)写持久层代码 5)生成测试类 MyBatis打印日志 传递参数 MyBatis的增、删、改 增(Insert࿰…...
c++ using 关键字
在C中,using 关键字有多种用途,但最常见的用途之一是在命名空间(namespace)中引入名称,以避免在代码中频繁使用命名空间前缀。此外,using 还可以用于类型别名(typedef 的替代品)和模…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...

Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...