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 测试

  1. 导入依赖
	<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
  1. 配置连接
# SpringBoot 所有的配置类,都有一个自动配置类,RedisAutoConfiguration;
# 自动配置类都会绑定一个 properties 文件,RedisProperties。# 配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
  1. 测试

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;}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/841144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++中的内存布局与数据存储详解

C中的内存布局和数据存储是指程序在运行时&#xff0c;如何在内存中组织和管理数据。这对于理解程序的性能、调试和优化非常重要。C程序的内存布局通常分为以下几个主要区域&#xff1a; 代码段&#xff08;Text Segment&#xff09;数据段&#xff08;Data Segment&#xff0…

C语言 | Leetcode C语言题解之第112题路径总和

题目&#xff1a; 题解&#xff1a; bool hasPathSum(struct TreeNode *root, int sum) {if (root NULL) {return false;}if (root->left NULL && root->right NULL) {return sum root->val;}return hasPathSum(root->left, sum - root->val) ||ha…

一个普通双非女生的秋招之路

大家好&#xff0c;我是小布丁。 先简单地做个自我介绍&#xff1a; 我今年本科毕业于某双非院校&#xff08;属于那种没什么人听说过的小学校&#xff09;&#xff0c;学的是计算机专业&#xff0c;英语四级水平&#xff08;没办法&#xff0c;六级确实没过&#xff09;。我本…

逃逸分析和标量替换有何区别

1、逃逸分析&#xff08;Escape Analysis&#xff09;&#xff1a; 逃逸分析是一种分析技术&#xff0c;用于判断一个对象&#xff08;通常是一个Java对象&#xff09;在方法执行过程中是否会被外部方法或线程所引用。它主要关注对象的动态作用域&#xff0c;即对象在方法执行…

从0开始带你成为Kafka消息中间件高手---第二讲

从0开始带你成为Kafka消息中间件高手—第二讲 那么在消费数据的时候&#xff0c;需要从磁盘文件里读取数据后通过网络发送出去&#xff0c;这个时候怎么提升性能呢&#xff1f; 首先就是利用了page cache技术&#xff0c;之前说过&#xff0c;kafka写入数据到磁盘文件的时候&…

企业微信hook接口协议,ipad协议http,根据手机号搜索联系人

根据手机号搜索联系人 参数名必选类型说明uuid是String每个实例的唯一标识&#xff0c;根据uuid操作具体企业微信 请求示例 {"uuid":"3240fde0-45e2-48c0-90e8-cb098d0ebe43","phoneNumber":"1357xxxx" } 返回示例 {"data&q…

如何使用Python的map()和filter()函数?

Python中的map()和filter()函数是处理可迭代对象&#xff08;如列表、元组等&#xff09;时非常有用的内置函数。 1. map()函数 map()函数将一个函数应用于一个输入列表&#xff08;或其他可迭代对象&#xff09;的所有元素&#xff0c;并返回一个包含所有函数返回值的迭代器…

【全网最全最详细】JavaSE基础面试题(未完待续...)

一、接口和抽象类的区别? 方法定义:接口和抽象类,最明显的区别就是接口只是定义了一些方法而已,在不考虑Java8中default方法情况下,接口中只有抽象方法,是没有实现的代码的。(Java8中可以有默认方法) 修饰符:抽象类中的修饰符可以有public、protected和private和<…

自动化办公:openpyxl操作Excel的7个示例

1. 引言&#xff1a;Python与Excel自动化办公的优势 在日常工作中&#xff0c;Excel作为数据分析和报告制作的利器&#xff0c;几乎无人不知无人不晓。然而&#xff0c;面对大量重复的数据录入、整理、分析任务时&#xff0c;手动操作不仅耗时费力&#xff0c;还容易出错。此时…

faster_whisper语音识别

faster_whisper语音识别 检测可用设备&#xff1a;list_available_devices()函数 我这边usb摄像头带麦克风的&#xff0c;所以 DEV_index 8 1 使用 pyaudio 打开音频设备 2 从音频设备读取数据&#xff0c;传递给 faster_whisper 识别 按键 r 录制 s 停止 q退出 test.py #…

隐私是建立人工智能信任的关键

微信关注公众号网络研究观获取更多。 谷歌的 Astra 是其首款人工智能代理 谷歌继续将生成式人工智能融入网络安全 云的复杂性是我们这个时代最大的安全威胁 云安全最受关注的问题&#xff1a;人工智能生成的代码 企业可以从人工智能中获得转型利益&#xff0c;但确保“隐…

CAD二次开发(4)-编辑图形

工具类&#xff1a;EditEntityTool.cs using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Th…

计划跳槽需要做哪些准备?

计划跳槽是一个复杂的过程&#xff0c;需要充分的准备和策略。以下是一些关键的准备步骤&#xff1a; 自我评估&#xff1a;首先&#xff0c;明确你跳槽的原因和目标。你想从新工作中得到什么&#xff1f;是更好的薪酬、职业发展、工作环境&#xff0c;还是其他因素&#xff1…

Leetcode | 5-22 | 每日一题 | 找出输掉零场或一场比赛的玩家

&#x1f525;博客介绍&#xff1a; EvLast &#x1f3a5;系列专栏&#xff1a; 数据结构与算法 , 算法入门 , C项目 , Leetcode_DayCode &#x1f3a5; 当前专栏: Leetcode_DayCode 专题 : 数据结构帮助小白快速入门算法 &#x1f44d;&#x1f44d;&#x1f44d;&#x1…

Go语言之Gorm框架(一) ——初窥Gorm框架

Gorm和Mysql驱动的安装 打开终端&#xff0c;输入下列命令即可&#xff1a; go get gorm.io/driver/mysql go get gorm.io/gormGorm连接数据库 示例 package mainimport ("fmt""github.com/sirupsen/logrus""gorm.io/driver/mysql""gor…

HE TB PPDU MU-RTS

看起来像是MU-RTS的触发帧的应答不是HE TB PPDU&#xff0c;而是传统得的帧&#xff0c;应答CTS。 非AP 的STA&#xff0c;是不能发送触发帧&#xff0c;也就是说&#xff0c;触发帧&#xff0c;只能是由AP发送给STA

AI视频智能分析引领智慧园区升级:EasyCVR智慧园区视频管理方案

一、系统概述与需求 随着信息技术的不断发展&#xff0c;智慧园区作为城市现代化的重要组成部分&#xff0c;对安全监控、智能化管理提出了更高的要求。智慧园区视频智能管理系统作为实现园区智能化管理的重要手段&#xff0c;通过对园区内各关键节点的视频监控和智能分析&…

一文了解安卓内存抖动

目录 目录一、什么是内存抖动&#xff1f;1.1 Android里的内存抖动1.2 如何直观查看这种现象1.3 内存抖动带来的风险 二、如何避免内存抖动 目录 一、什么是内存抖动&#xff1f; 在程序里&#xff0c;每创建一个对象&#xff0c;就会有一块内存分配给它&#xff0c;每分配一…

LabVIEW虚拟测试实验室开发

LabVIEW虚拟测试实验室开发 在当代的科技和工业进步中&#xff0c;测试与测量扮演着至关重要的角色。随着技术的发展&#xff0c;测试系统也变得日益复杂和成本昂贵&#xff0c;同时对测试结果的准确性和测试过程的效率要求越来越高。开发了一种基于LabVIEW的虚拟测试实验室的…

ICQ 将于 6 月关闭,这是一种奇怪的方式,发现它在 2024 年仍然活跃

你知道ICQ还活着吗&#xff1f;不过&#xff0c;不要太兴奋;它将永远消失。 还记得ICQ吗&#xff1f;如果你这样做了&#xff0c;你可能会记得它是AOL在1998年购买的Messenger客户端&#xff0c;就在Yahoo Instant Messager和MSN Messenger加入竞争的时候。然后Skype出现了&…