当前位置: 首页 > news >正文

Spring整合Redis基本操作步骤

Spring 整合 Redis 操作步骤总结

1. 添加依赖

首先,在 pom.xml 文件中添加必要的 Maven 依赖。Redis 相关的依赖包括 Spring Boot 的 Redis 启动器和 fastjson(如果需要使用 Fastjson 作为序列化工具):

<!-- Spring Boot Redis Starter -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><!-- Fastjson (用于 JSON 序列化和反序列化) -->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId>
</dependency>
2. 配置 Redis 连接信息

application.ymlapplication.properties 中配置 Redis 连接信息。以下是 application.yml 配置示例:

spring:redis:host: 127.0.0.1port: 6379database: 0jedis:pool:max-active: 20max-wait: -1max-idle: 10min-idle: 0timeout: 2000
3. 配置 Redis 数据源连接池

如果使用连接池(例如 HikariCP),你可以在 application.yml 中配置数据源连接池的参数。Spring Boot 默认会使用 HikariCP 连接池。

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/easylive?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverhikari:pool-name: HikariCPDatasourceminimum-idle: 5idle-timeout: 180000maximum-pool-size: 10auto-commit: truemax-lifetime: 1800000connection-timeout: 30000connection-test-query: SELECT 1
4. 创建 Redis 配置类

在 Spring Boot 中配置 RedisTemplateRedisMessageListenerContainer。以下是一个基本的 RedisConfig 类,它用于配置 Redis 连接、序列化方式等。

@Configuration
public class RedisConfig<V> {private static final Logger logger = LoggerFactory.getLogger(RedisConfig.class);// 配置 RedisTemplate@Bean("redisTemplate")public RedisTemplate<String, V> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, V> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 设置 key 和 value 的序列化方式template.setKeySerializer(RedisSerializer.string());template.setValueSerializer(RedisSerializer.json());template.setHashKeySerializer(RedisSerializer.string());template.setHashValueSerializer(RedisSerializer.json());template.afterPropertiesSet();return template;}// 配置 Redis 消息监听容器@Beanpublic RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);return container;}
}
5. 使用 RedisTemplate 执行 Redis 操作

RedisTemplate 是 Spring Data Redis 提供的核心工具,用于执行 Redis 操作。以下是如何使用 RedisTemplate 进行 Redis 数据的基本操作。

@Service
public class RedisService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;// 保存数据public void save(String key, Object value) {redisTemplate.opsForValue().set(key, value);}// 获取数据public Object get(String key) {return redisTemplate.opsForValue().get(key);}// 删除数据public void delete(String key) {redisTemplate.delete(key);}// 使用 Hash 存储数据public void saveHash(String hashKey, String key, Object value) {redisTemplate.opsForHash().put(hashKey, key, value);}public Object getHash(String hashKey, String key) {return redisTemplate.opsForHash().get(hashKey, key);}
}
6. Fastjson 作为序列化工具(可选)

如果你想使用 Fastjson 作为 Redis 数据的序列化和反序列化工具,可以在 RedisConfig 中配置:

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 使用 Fastjson 序列化template.setValueSerializer(new FastJsonRedisSerializer<>(Object.class));template.setHashValueSerializer(new FastJsonRedisSerializer<>(Object.class));template.afterPropertiesSet();return template;
}
7. 配置 Redis 消息监听器(可选)

如果你需要实现 Redis 发布/订阅功能,可以配置 RedisMessageListenerContainer 来监听 Redis 频道。

@Service
public class RedisListenerService {@Autowiredprivate RedisMessageListenerContainer container;public void subscribe(String channel) {MessageListener listener = message -> {String messageBody = new String(message.getBody());System.out.println("Received message: " + messageBody);};container.addMessageListener(listener, new ChannelTopic(channel));}
}
8. Redis 操作的示例

保存数据到 Redis

redisService.save("username", "john_doe");

获取 Redis 中的数据

String username = (String) redisService.get("username");

删除 Redis 中的数据

redisService.delete("username");
9. 总结

通过以上步骤,你已经成功将 Redis 集成到 Spring Boot 项目中,主要包括:

  • 配置 Redis 连接和连接池。
  • 配置 RedisTemplate 和使用序列化工具(如 Fastjson)。
  • 使用 RedisTemplate 执行常见的 Redis 操作(如 set/get)。
  • 配置 Redis 消息监听器实现发布/订阅功能(可选)。

此方案提供了高效的 Redis 集成方式,可以支持缓存、消息队列、发布/订阅等常见使用场景。

封装工具类

package com.easylive.redis;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;@Component("redisUtils")
public class RedisUtils<V> {@Resourceprivate RedisTemplate<String, V> redisTemplate;private static final Logger logger = LoggerFactory.getLogger(RedisUtils.class);/*** 删除缓存** @param key 可以传一个值 或多个*/public void delete(String... key) {if (key != null && key.length > 0) {if (key.length == 1) {redisTemplate.delete(key[0]);} else {redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));}}}public V get(String key) {return key == null ? null : redisTemplate.opsForValue().get(key);}/*** 普通缓存放入** @param key   键* @param value 值* @return true成功 false失败*/public boolean set(String key, V value) {try {redisTemplate.opsForValue().set(key, value);return true;} catch (Exception e) {logger.error("设置redisKey:{},value:{}失败", key, value);return false;}}public boolean keyExists(String key) {return redisTemplate.hasKey(key);}/*** 普通缓存放入并设置时间** @param key   键* @param value 值* @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期* @return true成功 false 失败*/public boolean setex(String key, V value, long time) {try {if (time > 0) {redisTemplate.opsForValue().set(key, value, time, TimeUnit.MILLISECONDS);} else {set(key, value);}return true;} catch (Exception e) {logger.error("设置redisKey:{},value:{}失败", key, value);return false;}}public boolean expire(String key, long time) {try {if (time > 0) {redisTemplate.expire(key, time, TimeUnit.MILLISECONDS);}return true;} catch (Exception e) {e.printStackTrace();return false;}}public List<V> getQueueList(String key) {return redisTemplate.opsForList().range(key, 0, -1);}public boolean lpush(String key, V value, Long time) {try {redisTemplate.opsForList().leftPush(key, value);if (time != null && time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}public long remove(String key, Object value) {try {Long remove = redisTemplate.opsForList().remove(key, 1, value);return remove;} catch (Exception e) {e.printStackTrace();return 0;}}public boolean lpushAll(String key, List<V> values, long time) {try {redisTemplate.opsForList().leftPushAll(key, values);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}public V rpop(String key) {try {return redisTemplate.opsForList().rightPop(key);} catch (Exception e) {e.printStackTrace();return null;}}public Long increment(String key) {Long count = redisTemplate.opsForValue().increment(key, 1);return count;}public Long incrementex(String key, long milliseconds) {Long count = redisTemplate.opsForValue().increment(key, 1);if (count == 1) {//设置过期时间1天expire(key, milliseconds);}return count;}public Long decrement(String key) {Long count = redisTemplate.opsForValue().increment(key, -1);if (count <= 0) {redisTemplate.delete(key);}logger.info("key:{},减少数量{}", key, count);return count;}public Set<String> getByKeyPrefix(String keyPrifix) {Set<String> keyList = redisTemplate.keys(keyPrifix + "*");return keyList;}public Map<String, V> getBatch(String keyPrifix) {Set<String> keySet = redisTemplate.keys(keyPrifix + "*");List<String> keyList = new ArrayList<>(keySet);List<V> keyValueList = redisTemplate.opsForValue().multiGet(keyList);Map<String, V> resultMap = keyList.stream().collect(Collectors.toMap(key -> key, value -> keyValueList.get(keyList.indexOf(value))));return resultMap;}public void zaddCount(String key, V v) {redisTemplate.opsForZSet().incrementScore(key, v, 1);}public List<V> getZSetList(String key, Integer count) {Set<V> topElements = redisTemplate.opsForZSet().reverseRange(key, 0, count);List<V> list = new ArrayList<>(topElements);return list;}}

这个 RedisUtils 类是一个通用的 Redis 工具类,封装了对 Redis 的常见操作,方便在项目中进行缓存处理、队列操作等。下面详细解释每个方法的功能。

1. delete 方法

public void delete(String... key) {if (key != null && key.length > 0) {if (key.length == 1) {redisTemplate.delete(key[0]);} else {redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));}}
}
  • 功能:删除指定的 Redis 键,可以一次删除一个或多个键。
  • 参数key:一个或多个 Redis 键名。
  • 实现
    • 如果只有一个键,调用 redisTemplate.delete(key[0]) 删除该键。
    • 如果有多个键,先将它们转换成一个 List,然后调用 redisTemplate.delete() 删除多个键。

2. get 方法

public V get(String key) {return key == null ? null : redisTemplate.opsForValue().get(key);
}
  • 功能:从 Redis 中获取指定键的值。
  • 参数key:Redis 键名。
  • 返回:键对应的值,如果键为空则返回 null
  • 实现:调用 redisTemplate.opsForValue().get(key) 获取 Redis 中保存的值。

3. set 方法

public boolean set(String key, V value) {try {redisTemplate.opsForValue().set(key, value);return true;} catch (Exception e) {logger.error("设置redisKey:{},value:{}失败", key, value);return false;}
}
  • 功能:将数据保存到 Redis 中,使用键值对存储。
  • 参数key:Redis 键名,value:要保存的值。
  • 返回:如果成功保存,返回 true,否则返回 false
  • 实现:调用 redisTemplate.opsForValue().set(key, value) 保存数据,如果发生异常则返回 false 并记录日志。

4. keyExists 方法

public boolean keyExists(String key) {return redisTemplate.hasKey(key);
}
  • 功能:检查 Redis 中是否存在指定的键。
  • 参数key:Redis 键名。
  • 返回:如果键存在返回 true,否则返回 false
  • 实现:调用 redisTemplate.hasKey(key) 检查键是否存在。

5. setex 方法

public boolean setex(String key, V value, long time) {try {if (time > 0) {redisTemplate.opsForValue().set(key, value, time, TimeUnit.MILLISECONDS);} else {set(key, value);}return true;} catch (Exception e) {logger.error("设置redisKey:{},value:{}失败", key, value);return false;}
}
  • 功能:将数据保存到 Redis 中,并设置过期时间。
  • 参数key:Redis 键名,value:要保存的值,time:过期时间,单位为毫秒。
  • 返回:保存成功返回 true,否则返回 false
  • 实现
    • 如果 time > 0,调用 redisTemplate.opsForValue().set(key, value, time, TimeUnit.MILLISECONDS) 保存数据并设置过期时间。
    • 如果 time <= 0,直接调用 set() 方法保存数据。

6. expire 方法

public boolean expire(String key, long time) {try {if (time > 0) {redisTemplate.expire(key, time, TimeUnit.MILLISECONDS);}return true;} catch (Exception e) {e.printStackTrace();return false;}
}
  • 功能:设置 Redis 键的过期时间。
  • 参数key:Redis 键名,time:过期时间,单位为毫秒。
  • 返回:设置成功返回 true,否则返回 false
  • 实现:调用 redisTemplate.expire(key, time, TimeUnit.MILLISECONDS) 设置过期时间。

7. getQueueList 方法

public List<V> getQueueList(String key) {return redisTemplate.opsForList().range(key, 0, -1);
}
  • 功能:获取 Redis 列表(队列)的所有元素。
  • 参数key:Redis 键名。
  • 返回:Redis 列表的所有元素,返回类型是 List<V>
  • 实现:调用 redisTemplate.opsForList().range(key, 0, -1) 获取整个列表。

8. lpush 方法

public boolean lpush(String key, V value, Long time) {try {redisTemplate.opsForList().leftPush(key, value);if (time != null && time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}
}
  • 功能:将元素插入到 Redis 列表的头部。
  • 参数key:Redis 键名,value:要插入的值,time:可选的过期时间,单位为秒。
  • 返回:插入成功返回 true,否则返回 false
  • 实现
    • 调用 redisTemplate.opsForList().leftPush(key, value) 将元素添加到列表头部。
    • 如果 time > 0,则调用 expire() 方法设置过期时间。

9. remove 方法

public long remove(String key, Object value) {try {Long remove = redisTemplate.opsForList().remove(key, 1, value);return remove;} catch (Exception e) {e.printStackTrace();return 0;}
}
  • 功能:从 Redis 列表中删除指定元素。
  • 参数key:Redis 键名,value:要删除的值。
  • 返回:删除成功返回被删除的元素数量,失败返回 0
  • 实现:调用 redisTemplate.opsForList().remove(key, 1, value) 删除元素。

10. lpushAll 方法

public boolean lpushAll(String key, List<V> values, long time) {try {redisTemplate.opsForList().leftPushAll(key, values);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}
}
  • 功能:将多个元素插入到 Redis 列表的头部。
  • 参数key:Redis 键名,values:要插入的值列表,time:可选的过期时间,单位为秒。
  • 返回:插入成功返回 true,否则返回 false
  • 实现
    • 调用 redisTemplate.opsForList().leftPushAll(key, values) 将多个元素插入到列表头部。
    • 如果 time > 0,则调用 expire() 方法设置过期时间。

11. rpop 方法

public V rpop(String key) {try {return redisTemplate.opsForList().rightPop(key);} catch (Exception e) {e.printStackTrace();return null;}
}
  • 功能:从 Redis 列表的尾部弹出一个元素。
  • 参数key:Redis 键名。
  • 返回:弹出的元素,如果发生异常则返回 null
  • 实现:调用 redisTemplate.opsForList().rightPop(key) 弹出列表尾部元素。

12. increment 方法

public Long increment(String key) {Long count = redisTemplate.opsForValue().increment(key, 1);return count;
}
  • 功能:将指定键的值增加 1(如果键不存在,则创建并设置为 1)。
  • 参数key:Redis 键名。
  • 返回:增加后的值。
  • 实现:调用 redisTemplate.opsForValue().increment(key, 1) 增加值。

13. incrementex 方法

public Long incrementex(String key, long milliseconds) {Long count = redisTemplate.opsForValue().increment(key, 1);if (count == 1) {expire(key, milliseconds);}return count;
}
  • 功能:将指定键的值增加 1,并在首次设置时设置过期时间。
  • 参数key:Redis 键名,`milliseconds

相关文章:

Spring整合Redis基本操作步骤

Spring 整合 Redis 操作步骤总结 1. 添加依赖 首先&#xff0c;在 pom.xml 文件中添加必要的 Maven 依赖。Redis 相关的依赖包括 Spring Boot 的 Redis 启动器和 fastjson&#xff08;如果需要使用 Fastjson 作为序列化工具&#xff09;&#xff1a; <!-- Spring Boot Re…...

STM32使用SFUD库驱动W25Q64

SFUD简介 SFUD是一个通用SPI Flash驱动库&#xff0c;通过SFUD可以库轻松完成对SPI Flash的读/擦/写的基本操作&#xff0c;而不用自己去看手册&#xff0c;写代码造轮子。但是SFUD的功能不仅仅于此&#xff1a;①通过SFUD库可以实现在一个项目中对多个Flash的同时驱动&#x…...

ArKTS基础组件

一.AlphabetIndexer 可以与容器组件联动用于按逻辑结构快速定位容器显示区域的组件。 子组件 color:设置文字颜色。 参数名类型必填说明valueResourceColor是 文字颜色。 默认值&#xff1a;0x99182431。 selectedColor:设置选中项文字颜色。 参数名类型必填说明valueRes…...

如何理解TCP/IP协议?如何理解TCP/IP协议是什么?

理解TCP/IP协议 1. 什么是TCP/IP协议? TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是一组用于实现网络通信的协议,广泛用于互联网和局域网中。TCP/IP协议栈由一系列协议组成,规定了计算机如何在网络中发送和接收数据。它通常被用来…...

如何使用 Python 连接 SQLite 数据库?

SQLite是一种轻量级的嵌入式数据库&#xff0c;广泛应用于各种应用程序中。 Python提供了内置的sqlite3模块&#xff0c;使得连接和操作SQLite数据库变得非常简单。 下面我将详细介绍如何使用sqlite3模块来连接SQLite数据库&#xff0c;并提供一些实际开发中的建议和注意事项…...

【博弈模型】古诺模型、stackelberg博弈模型、伯特兰德模型、价格领导模型

博弈模型 1、古诺模型&#xff08;cournot&#xff09;&#xff08;1&#xff09;假设&#xff08;2&#xff09;行为分析&#xff08;3&#xff09;经济后果&#xff08;4&#xff09;例题 2、stackelberg博弈模型&#xff08;产量领导模型&#xff09;&#xff08;1&#xff…...

单片机:实现花样灯数码管的显示(附带源码)

单片机实现花样灯数码管显示 数码管&#xff08;七段数码管&#xff09;广泛用于数字显示&#xff0c;例如时钟、计数器、温度计等设备。在本项目中&#xff0c;我们将使用单片机实现花样灯数码管的显示效果。所谓花样灯显示是指通过控制数码管上的各个段位&#xff0c;以不同…...

什么是芯片电阻

有人把Chip Resistor翻译成“芯片电阻”&#xff0c;我觉得翻译成“贴片电阻”或“片状电阻”更合适。有些厂商也称之为”电阻片”&#xff0c;英文写作Resistor Chip。比如&#xff1a;Thick film resistor chips&#xff08;厚膜电阻片&#xff09;、Thin film resistor chip…...

【C++】sophus : geometry.hpp 位姿(SE2 和 SE3)和(2D 直线\3D 平面)转换函数 (五)

这段代码定义了一系列在位姿&#xff08;SE2 和 SE3&#xff09;和几何实体&#xff08;2D 直线和 3D 平面&#xff09;之间进行转换的函数。它利用了 Sophus 库中已有的旋转表示&#xff08;SO2 和 SO3&#xff09;。 以下是函数的详细解释&#xff1a; 1. SO2 与直线&#xf…...

moment()获取时间

moment 是一个 JavaScript 日期处理类库。 使用&#xff1a; //安装 moment npm install moment -- save引用 //在main.js中全局引入 import moment from "moment"设定moment区域为中国 //import 方式 import moment/locale/zh-cn moment.locale(zh-cn); 挂载全…...

Azure虚拟机非托管磁盘大小调整

想要扩容一个Azure VM 的磁盘空间&#xff0c;门户里面竟然无法扩展&#xff0c;点点鼠标就完事的时代在离去&#xff0c;微软越来不想微软。 在门户里面即便使用Azure Cli命令行也不行。 PS /home/gpchina> az disk list [] 返回为空&#xff0c;根本没有返回磁盘。 不过使…...

流匹配模型[Flow Matching]

流匹配模型&#xff1a;概念、优缺点与扩散模型的对比 在生成建模领域&#xff0c;流匹配模型&#xff08;Flow Matching&#xff09;是一种通过学习流场将初始分布&#xff08;通常是高斯噪声&#xff09;变换为目标分布的新型框架。本文将对流匹配模型的概念、与扩散模型的联…...

Unix 和 Windows 的有趣比较

Unix 和 Windows NT 比较 来源于这两本书&#xff0c;把两本书对照来读&#xff0c;发现很多有意思的地方&#xff1a; 《Unix 传奇》 https://book.douban.com/subject/35292726/ 《观止 微软创建NT和未来的夺命狂奔 》 Showstopper!: The Breakneck Race to Create Windows…...

算法(三)——贪心算法

文章目录 定义基本原理基本思路优缺点优点缺点 经典案例及解析找零问题问题描述贪心思路算法解析java代码示例 活动选择问题问题描述贪心思路算法解析java代码示例 车辆路径问题问题描述贪心思路算法分析java代码示例 定义 贪心算法是指在求解问题时&#xff0c;总是做出在当前…...

LeetCode 704.二分查找

LeetCode 704.二分查找 思路&#x1f9d0;&#xff1a; 在本篇以及之后几篇的博客中&#xff0c;博主将会用二分法进行解答&#xff0c;以此巩固二分题型。二分法一般用于具有二段性的数据中使用。比如该题为有序数组&#xff0c;需要我们查找一个目标值target&#xff0c;分析…...

Linux介绍与安装CentOS 7操作系统

什么是操作系统 操作系统&#xff0c;英⽂名称 Operating System&#xff0c;简称 OS&#xff0c;是计算机系统中必不 可少的基础系统软件&#xff0c;它是 应⽤程序运⾏以及⽤户操作必备的基础环境 ⽀撑&#xff0c;是计算机系统的核⼼。 操作系统的作⽤是管理和控制计算机系…...

使用 rbenv 切换 Ruby 版本

1. 查看当前 Ruby 版本 首先&#xff0c;查看当前系统中安装的 Ruby 版本&#xff1a; ruby -v如果你已经安装了 rbenv&#xff0c;可以列出通过 rbenv 安装的 Ruby 版本&#xff1a; rbenv versions2. 安装 Ruby 版本 如果你想安装新的 Ruby 版本&#xff0c;使用以下命令…...

C语言(结构体练习)

设计一个结构体,存放一个学员信息并显示&#xff0c;存放两个学员信息&#xff0c;算他们的平均分。 #include <stdio.h> #include <string.h>// 定义结构体 typedef struct {char name[50];float score; } Student;// 函数声明 void display(Student student); f…...

你了解网络层的 ICMP 吗?

你了解网络层的 ICMP 吗&#xff1f; 一. 什么是 ICMP二. ICMP 的工作原理三. ICMP 的结构四. ICMP 的常见应用五. ICMP 的局限性与安全性六. 总结 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神…...

清理C盘小记

突然C盘就爆满了&#xff0c;想当初还是给他预留了120G的空间&#xff0c;感觉到现在也不够用了&#xff0c;担心出现死机的情况就赶紧进行了清理。有一说一&#xff0c;清理回收站是真的有用。 参考&#xff1a;C盘清理指南&#xff0c;清理出30G起&#xff0c;超详细总结&am…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...

Pydantic + Function Calling的结合

1、Pydantic Pydantic 是一个 Python 库&#xff0c;用于数据验证和设置管理&#xff0c;通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发&#xff08;如 FastAPI&#xff09;、配置管理和数据解析&#xff0c;核心功能包括&#xff1a; 数据验证&#xff1a;通过…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...