【MySQL】存储过程,存储函数,触发器
目录
准备工作
一. 存储过程
1.1.什么是存储过程
1.2.创建存储过程
1.3.创建只显示大于等于指定值的记录的存储过程
1.4.显示,删除存储过程
二. 存储函数
2.1.什么是存储函数
2.2.使用存储函数
2.2.1.使用存储函数之前
2.2.2.使用存储函数计算标准体重
2.2.3.返回记录平均值的存储函数
2.3.显示和删除存储函数
三. 触发器
3.1.什么是触发器
3.2.创建触发器
3.2.1.触发器被触发的时机
3.2.2.创建触发器
3.3.触发器的内容
3.4.确认和删除触发器
3.4.1. 查看所有触发器
3.4.2.删除触发器
准备工作
我们得先创建好两个表tb和tb1
-- 如果表已存在则删除
DROP TABLE IF EXISTS `tb1`;-- 创建 tb1 表(员工信息表)
CREATE TABLE `tb1` (`empid` VARCHAR(4) PRIMARY KEY COMMENT '员工编号',`name` VARCHAR(50) COMMENT '员工姓名',`age` INT COMMENT '员工年龄'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 插入员工数据(注意:没有 A105)
INSERT INTO `tb1` (`empid`, `name`, `age`) VALUES
('A101', '佐藤', 40),
('A102', '高桥', 28),
('A103', '中川', 20),
('A104', '渡边', 23),
('A105', '西泽',35);-- 如果表已存在则删除
DROP TABLE IF EXISTS `tb`;-- 创建 tb 表(销售信息表)
CREATE TABLE `tb` (`empid` VARCHAR(4) COMMENT '员工编号(关联 tb1.empid)',`sales` INT COMMENT '销售额',`month` INT COMMENT '月份'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 插入销售数据(包含 A107,但 tb1 中无对应员工)
INSERT INTO `tb` (`empid`, `sales`, `month`) VALUES
('A103', 101, 4),
('A102', 54, 5),
('A104', 181, 4),
('A101', 184, 4),
('A103', 17, 5),
('A101', 300, 5),
('A102', 205, 6),
('A104', 93, 5),
('A103', 12, 6),
('A107', 87, 6);
我们现在开始进入正题
一. 存储过程
1.1.什么是存储过程
MySQL存储过程是一种预先编写并存储在数据库中的可重复使用的SQL代码块,它能够通过一个名称被调用执行。
存储过程可以包含复杂的逻辑操作,如条件判断、循环、变量操作等,允许将一系列SQL语句组合成一个单元,以便在需要时高效执行。
换句话说,就是将多个 SQL 语句组合成一个只需要使用命令“CALL xx”就能执行的集合,该集合就称为存储过程(stored procedure )。
“存储”( stored)表示保存,“过程”(procedure)表示步骤。也就是说,存储过程是将一系列步骤归纳并存储起来的集合
与直接在应用程序中编写SQL语句相比,存储过程将业务逻辑封装在数据库层,提升了代码的模块化和可维护性。
由于可以自动执行许多事先准备好的命令,所以处理效率很高。
但是,在存储了重要数据的数据库中,执行没有经过充分验证的存储过程是非常危险的,这一点需要我们牢记。
存储过程乍一看让人觉得有些难以理解,但只要学会了它的使用方法,用起来就会非常方便。
下面是作为示例创建的存储过程的主体。
SELECT * FROM tb;
SELECT * FROM tb1;
上面的示例中只列出了两个很普通的 SQL语句。
当然,我们也可以根据需要编写任意数量的SQL语句,还可以执行编程语言中常见的处理,比如使用变量、使用IF和 CASE作为条件分支以及使用 WHILE 和 REPEAT 反复处理等。
1.2.创建存储过程
当创建存储过程时,我们需要像下面这样执行 CREATE PROCEDURE 命令。
CREATE PROCEDURE 存储过程名 ( )
BEGINSQL 语句 1SQL 语句 2
END
从 BEGIN 到 END 为止的内容是存储过程的主体。
在开头加上 BEGIN,在结尾加上 END,这么做可以明确表示“从这里到这里是存储过程的命令”。
因为存储过程的内容是“普通的 SQL 语句”,所以需要在命令的末尾添加分隔符“;”。
也就是说,当创建上面我们说的那个示例介绍的存储过程时,主体部分需要像下面这样描述。
BEGIN
SELECT * FROM tb;
SELECT * FROM tbl;
END
可是这样一来,在创建存储过程的时候就会输入分隔符“;”。在这种情况下,CREATE PROCEDURE 命令就会在存储过程不完整的状态下执行。因为在 MySQL 监视器中一旦输入了分隔符,不管是什么内容,都会先执行分隔符之前的部分。
- 修改分隔符的设置
在存储过程不完整的状态下执行命令会带来一些麻烦,因此我们需要改变环境设置,在输入了最后的 END 之后再执行 CREATE PROCEDURE 命令。
因此,在创建存储过程时,需要事先将分隔符从“;”修改为其他符号,一般使用“//”。
我们可以使用 delimiter 命令将分隔符修改为“//”。
将分隔符修改为“//”
delimiter //
如果将分隔符设置为“//”,那么即使在创建存储过程的途中输入了“;”也不会发生任何问题。
在 END 之后输入“//”,这时就会执行 CREATE PROCEDURE 命令。
存储过程创建结束后,使用“delimiter ;”将分隔符恢复为原始设置。
下面我们来实际操作一下。
创建一个执行“SELECT * FROM tb;”和“SELECT * FROM tb1;”的存储过程 pr1。
最后的“delimiter ;”是把分隔符恢复为“;”的命令。不要忘记恢复分隔符。
另外,一定要在存储过程名的后面加上()。之后会介绍将值作为参数放在存储过程中的示例,但即使不输入值也必须加上()。
- 执行存储过程
这样就创建好了存储过程 pr1
。下面我们来试着使用这个存储过程。执行存储过程需要使用 CALL
命令。
CALL 存储过程名;
调用上一节创建的 prl
。
CALL pr1;
也是成功连续执行了“SELECT * FROM tb;”和“SELECT * FROM tb1;”这两条命令
1.3.创建只显示大于等于指定值的记录的存储过程
接下来试着创建带参数(→ 8.2.2 节)的存储过程。将需要处理的数据指定为()中的参数,并执行存储过程。
在存储过程中,我们可以像下面这样编写参数。
CREATE PROCEDURE 存储过程名 (参数名 数据类型);
这里,我们来创建一个“显示销售额大于等于指定值的记录”的基本存储过程。
例如,当向存储过程 prpr 中指定整数类型参数 d 时,存储过程就可以编写为 PROCEDURE pr (d INT)。参数 d 在 SQL 语句中的编写方式与普通数值相同。
例如,当处理下面这种情况时,
- 显示表中 sales 大于等于参数 d 的记录
SQL 语句可以编写成如下形式。
SELECT * FROM tb WHERE sales>=d;
下面我们就创建存储过程pr2。如果指定整数类型的参数d的值执行该存储过程,表tb中销售额大于等于d的记录就会显示出来。
下面我们就试着把200指定为参数来执行存储过程pr2。
call pr2(200);
1.4.显示,删除存储过程
我们可以使用下面这个命令来显示存储过程的内容
show create procedure 存储过程名;
- 删除存储过程
和删除数据库,表格,视图一样,我们可以使用drop命令删除存储过程
drop procedure 存储过程名;
下面的执行结果表示删除了存储过程pr1
二. 存储函数
说明一下:存储函数只能在mysql5.0以及更高的版本中使用
2.1.什么是存储函数
如图所示, 存储函数(storedf Unction)的思考方式和操作方法与存储过程基本相同,与 存储过程唯一不同的一点是,存储函数在执行后会返回—个值。
正如它的名字所表达的那样,存储函数可以作为函数工作。
虽然 MySQL 中有许多函数,但使用存储函数可以创建自定义的函数。所以存储函数也称为用户自定义函数。
存储函数返回的值可以在 SELECT 和 UPDATE 等命令中和普通函数一样使用。
我们可以使用以下语句创建存储函数。
CREATE FUNCTION 存储函数名(参数 数据类型)RETURNS 返回值的数据类型
BEGIN
SQL 语句
RETURN 返回值:表达式
END
和存储过程一样,我们可以在()内指定参数。即使没有指定参数,也必须加上()。
例如,当创建了名为 f_u 的存储函数时,f_u() 本身将返回存储函数中 RETURN x x 的 x x 部分。
2.2.使用存储函数
2.2.1.使用存储函数之前
在使用存储函数之前需要修改一处设置。
存储函数有可能对复制和数据的恢复产生影响。
因此,参数 log_bin_trust_function_creators 的初始值被设置为 0,这样就不能使用存储函数了。
要想使用存储函数,就需要执行下面的操作修改此设置。
当然,在我介绍的范围内修改这个设置不会产生任何问题,请大家放心。
- 临时设置(重启失效)
-- 启用存储函数创建权限
SET GLOBAL log_bin_trust_function_creators = 1;
-- 验证设置是否生效
SHOW VARIABLES LIKE 'log_bin_trust_function_creators';
- 永久设置(需修改配置文件)
编辑 MySQL 配置文件(如 my.cnf
或 my.ini
):
log_bin_trust_function_creators = 1
重启 MySQL 服务:
systemctl restart mysql
我们这里只使用临时修改的方式来修改log_bin_trust_function_creators
如果 log_bin_trust_function_creators 被设置成了 ON,就可以使用存储函数了。
另外,如果我们采用临时修改的方式的话,重新启动 MySQL,log_bin_trust_function_creators 的值将变回 OFF。如果想使用存储函数,就需要再次执行上述操作。
当然,也可以通过在 MySQL 的配置文件中或者在启动 MySQL 时指定相应的内容,让 log_bin_trust_function_creators 的值始终为 ON。
慎重起见,本书没有修改配置文件,而是通过修改 log_bin_trust_function_creators 的值进行了设置。
另外,使用存储函数还需要相应的权限。即使设置 log_bin_trust_function_creators=1
,用户仍需具备 CREATE ROUTINE
权限才能创建存储函数。普通用户可能需要额外授权。
大家使用的 root 用户中已经包含了这个权限(Super 权限),但是普通用户就需要额外添加权限了。
2.2.2.使用存储函数计算标准体重
光看文字介绍可能不太容易理解存储函数。虽然和数据库这个主题不太相符,不过这里作为练习,我们来试着计算一下自己的标准体重。
如果 BMI=22 为标准体重,则有如下等式。
标准体重 = 身高(cm)× 身高(cm)× 22/10000
我们试着使用这个等式来创建存储函数 fun。
这里我们把以厘米为单位的身高值作为参数,并指定参数名为 height,类型为整数类型。
我们需要使用下面的命令在存储函数 fun 中指定 INT 类型的参数。
CREATE FUNCTION fun(height INT)
存储函数自身会返回值。因此,必须对存储函数自身返回值的数值类型进行指定。
存储函数 fun 返回的是包含小数的标准体重,所以我们将存储函数 fun 返回值的数据类型指定为可以处理小数部分的 DOUBLE 类型。
具体命令如下所示。
CREATE FUNCTION fun(height INT) RETURNS DOUBLE
接着在存储函数中,对输入的 height 值取平方,再乘以 22,然后除以 10000,最后通过 RETURN 返回计算出来的值。这部分内容需要用到如下命令。
RETURN height * height *22/10000;
下面试着创建一个自定义的标准体重处理函数。创建以厘米为单位的身高值指定给参数height后,就能返回标准体重的存储函数fu1。
下面我们试着按身高180cm来计算一下标准体重。
这次让fu1作为函数来返回值。因此我们不使用 CALL,而是使用 SELECT命令来显示 fu1()的值。()内输人的参数值为180。
SELECT fu1(180);
2.2.3.返回记录平均值的存储函数
试着创建一个存储函数来返回某列中数据的平均值。事先创建好这样的函数,使用的时域就会非常方便。
以下内容用于创建存储函数 `fu2` 来返回表中中列 `sales` 的平均值。
编程经验少的人可能不太明白变量的相关处理,这里我们先创建好这个存储函数。
变量的含义将在后面进行介绍。
目的部分与前一节一样,它用于定义存储函数 `fu2` 的返回值为 `DOUBLE` 类型。
CREATE FUNCTION fuz() RETURNS DOUBLE
平均值需要通过 `SELECT AVG()` 来计算。这个值必须赋给变量。我们可以把变量理解为“保管值的箱子”。要想使用变量,就需要事先通过 `DECLARE` 定义变量。
- 通过 DECLARE 定义变量
DECLARE 变量名 数据类型;
这里我们把变量名设置成了 `r`。平均值会输入到变量 `r` 中。为了能够处理小数部分,我们将数据类型指定为 `DOUBLE` 类型。
将变量 `r` 定义为 `DOUBLE` 类型的命令,即
DECLARE r DOUBLE;
下面的 SQL 语句用于从表中提取列 `sales` 的平均值。
SELECT AVG(sales) FROM tb;
把 `AVG(sales)` 赋给 `DECLARE` 中定义的变量 `r` 时需要使用 `INTO`。
于是,SQL 语句就变成了下面这部分
SELECT AVG(sales) INTO r FROM tb;
这样,平均值就输入到了变量 `r` 中。我们可以使用`RETURN` 让这个平均值作为存储函数的值返回。
return r;
我们来使用一下
2.3.显示和删除存储函数
这个和上面的存储过程基本上是一模一样的。
- 查看存储函数
show create function 存储函数名;
- 删除存储函数
drop function 存储函数名;
三. 触发器
3.1.什么是触发器
触发器(trigger)是一种对表执行某操作后会触发执行其他命令的机制。
当执行 INSERT、UPDATE 和 DELETE 等命令时,作为触发器提前设置好的操作也会被执行例如,创建一个触发器,当某表的记录发生更新时,就以此为契机将更新的内容记录到另一个表中。
触发器也常作为处理的记录或者处理失败时的备份使用。
触发器是一个非常强大的功能,只通过文字介绍很难了解到这个功能有哪些优点。
我们先创建一个触发器来体验一下。这里我们来创建一个“如果删除了表中的记录,被删除的记录就会复制到其他表中”的触发器。
也就是说,如果对表tb1执行“DELETE FROM tb1…;”命令,被删除的记录就会全部插人到表 tb1 _fom 中。
这样一来,我们就可以随时恢复已删除的记录了。
请事先创建一个空表tb1_from 用于插入表 tb1 中删除的记录。我们可以通过复制表 tb1 的列结构来创建这个表.
create table tb1_from like tb1;
3.2.创建触发器
3.2.1.触发器被触发的时机
- 触发器的触发时机
触发器可以在以下两种时机执行:
-
BEFORE:在对表进行 INSERT、UPDATE、DELETE 操作之前触发。
-
AFTER:在对表进行 INSERT、UPDATE、DELETE 操作之后触发。
- 访问新旧列值
通过 OLD
和 NEW
关键字可以访问操作前后的列值:
-
OLD.列名:获取操作前的列值(适用于 UPDATE 和 DELETE)。
-
NEW.列名:获取操作后的列值(适用于 INSERT 和 UPDATE)。
- 不同命令下 OLD/NEW 的可用性
命令 | BEFORE 触发时(OLD) | AFTER 触发时(NEW) |
---|---|---|
INSERT | ×(不可用) | ○(可用) |
DELETE | ○(可用) | ×(不可用) |
UPDATE | ○(可用) | ○(可用) |
3.2.2.创建触发器
实际操作一下会更容易理解。创建触发器的具体命令如下所示。
格式:创建触发器
CREATE TRIGGER 触发器名 BEFORE (或者 AFTER) DELETE 等命令
ON 表名 FOR EACH ROW
BEGIN
使用更新前 (OLD, 列名) 或者更新后 (NEW, 列名) 的处理
END
在触发器主体的描述中,各个命令的末尾需要加上“.”。
与创建存储过程时相同,我们需要事先将分隔符改为“//”等。
下面来创建将表 tb1 中删除的记录插入到表 tb1_from 中的触发器。
触发器创建成功了。
我们先来体验一下触发器的效果。
现在,表 tb1 中删除的记录应该能够插入到表 tb1_from 中了。不管是 1 条记录还是 2 条记录,触发器都会进行处理,所以我们干脆把所有记录都删掉,然后使用 “SELECT * FROM tb1;” 命令确认记录是否真的被删除了。
DELETE FROM tb1;
select * from tb1;
执行结果中显示了 Empty set,没有显示任何记录。表 tb1 中已经没有记录了。那么,设置的触发器是否正常工作了呢?下面,我们来看一下表 tb1_from 中的内容。
SELECT * FROM tb1_from;
和我们预想的一样,删除的记录插入到了表 tb1_from 中。(SELECT 显示的顺序可能会发生改变。)
由此可见,触发器正常工作了。
在没有正常工作的情况下,请确认一下输入历史。大多是编写错误所致。我们可以使用 SHOW 命令来确认触发器的内容。如果发现触发器 tr1 的内容有问题,请使用 “DROP TRIGGER trl;” 予以删除,然后重新创建触发器。
下面将插入到表 tbl_from 中的记录恢复到原来的表 tbl 中。我们可以使用下面的命令进行复制。
INSERT INTO tb1 SELECT * FROM tb1_from;
3.3.触发器的内容
下面看一下触发器的内容。
CREATE TRIGGER trl BEFORE DELETE ON tbl FOR EACH ROW
BEGIN
INSERT INTO tbl_from VALUES(OLD.empid,OLD.name,OLD.age);
END
//
首先为表 tbl 的 DELETE 命令设置触发器 tr1。for each row就是对每一行都生效
因为要对删除之前(BEFORE)的值进行 INSERT,所以 CREATE TRIGGER 的部分需要编写成下面这样。
CREATE TRIGGER tr1 BEFORE DELETE ON tbl FOR EACH ROW
提取删除记录前(BEFORE)的列值(OLD. 列名),并将其插入表 tb1_from 中。表 tb1_from 由列 empid、列 name 和列 age 组成,所以删除记录前的列值分别为 OLD.empid、OLD.name 和 OLD.age。
因为要使用 INSERT 命令将这些列值插入到表 tb1_from 中,所以触发器需要描述成下面这样。
INSERT INTO tb1_from VALUES(OLD.empid,OLD.name,OLD.age);
该触发器的主体部分用 BEGIN 和 END 括了起来。
3.4.确认和删除触发器
3.4.1. 查看所有触发器
使用 SHOW TRIGGERS
命令可以列出当前数据库中的所有触发器及其基本信息:
SHOW TRIGGERS;
输出字段说明
字段 | 含义 |
---|---|
Trigger | 触发器名称(例如 trl )。 |
Event | 触发事件(如 DELETE 、INSERT 、UPDATE )。 |
Table | 触发器关联的表名(例如 tbl )。 |
Statement | 触发器执行的逻辑语句(例如 INSERT INTO tbl_from ... )。 |
Timing | 触发时机(BEFORE 或 AFTER )。 |
Created | 触发器创建时间。 |
sql_mode | 触发器创建时的 SQL 模式。 |
Definer | 触发器的创建者(用户和主机)。 |
3.4.2.删除触发器
为了防止意外执行处理’我们需要删除不需要的触发器。
drop tigger 触发器名;
试着触发器tr1,请执行以下操作
drop trigger tr1;
这样子触发器tr1就被删除了。
相关文章:
【MySQL】存储过程,存储函数,触发器
目录 准备工作 一. 存储过程 1.1.什么是存储过程 1.2.创建存储过程 1.3.创建只显示大于等于指定值的记录的存储过程 1.4.显示,删除存储过程 二. 存储函数 2.1.什么是存储函数 2.2.使用存储函数 2.2.1.使用存储函数之前 2.2.2.使用存储函数计算标准体重 …...
python打卡第29天
知识点回顾 类的装饰器装饰器思想的进一步理解:外部修改、动态类方法的定义:内部定义和外部定义 作业:复习类和函数的知识点,写下自己过去29天的学习心得,如对函数和类的理解,对python这门工具的理解等&…...
vim - v
在 Vim 中,使用 可视模式(Visual Mode) 可以选中文本并进行复制、剪切、粘贴等操作。以下是详细的使用方法: 1. 进入可视模式 命令功能v字符可视模式(按字符选择)V(大写)行可视模式…...
Linux 线程(上)
前言:大家早上中午晚上好!!今天来学习一下linux系统下所谓的线程吧!!! 一、重新理解进程,什么是进程? 1.1 图解 其中黑色虚线部分一整块就是进程,注意:一整…...
# 终端执行 java -jar example.jar 时(example.jar为项目jar包)报错:“没有主清单属性” 的解决方法
终端执行 java -jar example.jar 时(example.jar为项目jar包)报错:“没有主清单属性” 的解决方法 在Java中,一个JAR文件必须包含一个主清单属性(Main-Class属性)才能在命令行中直接运行。如果你在尝试运行…...
4:OpenCV—保存图像
将图像和视频保存到文件 在许多现实世界的计算机视觉应用中,需要保留图像和视频以供将来参考。最常见的持久化方法是将图像或视频保存到文件中。因此,本教程准备解释如何使用 OpenCV C将图像和视频保存到文件中。 将图像保存到文件 可以学习如何保存从…...
[C++面试] const相关面试题
1、非 const 的引用必须指向一个已存在的变量 int main() {int &a 20; // 错误const int &b 30; } 字面量 20 是临时值(右值),没有明确的内存地址。非常量引用(左值引用)不能直接绑定到右值(如…...
#Redis黑马点评#(六)Redis当中的消息队列
目录 Redis当中的消息队列 一 基于List 二 基于PubSub 三 基于Stream 单消费模式 消费者组 Redis当中的消息队列 消息队列,字面意思就是存放消息的队列。最简单的消息队列模型包括3个角色: 消息队列:存储和管理消息,也称为…...
Git基础原理和使用
Git 初识 一、版本管理痛点 在日常工作和学习中,我们经常遇到以下问题: - 通过不断复制文件来保存历史版本(如报告-v1、报告-最终版等) - 版本数量增多后无法清晰记住每个版本的修改内容 - 项目代码管理存在同样问题 二、版本控…...
Java程序员学AI(一)
一、前言 最近刷技术圈,满眼都是 GPT、DeepSeek、QWen 这些 AI 名词。看着同行们在群里聊 AI 写代码、做数据分析,我这个摸了 Java 老程序员突然慌了 —— 再不出手,怕是真要被时代落下了! 作为一个 Java 死忠粉,学 …...
《Python星球日记》 第91天:端到端 LLM 应用(综合项目:医疗文档助手)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、项目概述与需求分析1. 项目背景2. 项目目标3. 技术栈概览二、数据准备与处理1. 文档收集策略2. 文本预处理流程3. 向量化与知识库构建三、模…...
目前主流的AI测试工具推荐
以下是目前备受关注的AI测试工具及平台,涵盖功能测试、视觉测试、性能测试及国产化解决方案等多个领域,结合其核心特性与适用场景进行综合推荐: 一、主流AI测试工具推荐 Testim 核心功能:基于AI的动态元素定位技术,…...
vscode优化使用体验篇(快捷键)
本文章持续更新中 最新更新时间为2025-5-18 1、方法查看方法 1.1当前标签跳到新标签页查看方法实现 按住ctrl 鼠标左键点击方法。 1.2使用分屏查看方法实现(左右分屏) 按住ctrl alt 鼠标左键点击方法。...
uniprot中PTM数据的下载
首先是PTM的介绍: 参考:https://en.wikipedia.org/wiki/Post-translational_modification 蛋白质的翻译后修饰(PTM)通过改变氨基酸残基的化学结构,显著影响其带电性质,从而调控蛋白质的功能、定位和相互作…...
【QGIS二次开发】地图编辑-04
系列目录: 【QGIS二次开发】地图显示与交互-01_qgis二次开发加载地图案例-CSDN博客 【QGIS二次开发】地图显示与交互-02_setlayerlabeling-CSDN博客 【QGIS二次开发】地图符号与色表-03-CSDN博客 4 地图编辑 4.1 添加点要素 功能演示: 运行程序后…...
Qt 信号和槽-核心知识点小结(11)
目录 小结表格索引 disconnect函数 lambda表达式 啥是耦合,啥是内聚 简介:这是Qt信号和槽的最后一篇文章,最主要的是总结该信号和槽的核心知识点。以及该核心知识点的文章索引(表格太长了,手机可能看不完整&#…...
React响应事件中onClick={handleClick} 的结尾有没有小括号的区别
你可以通过在组件中声明 事件处理 函数来响应事件: function MyButton() {function handleClick() {alert(You clicked me!);}return (<button onClick{handleClick}>点我</button>);} 注意,onClick{handleClick} 的结尾没有小括号&#x…...
React-Query使用react-testing-library进行测试
1.测试react-query首先我们必须得拥有queryClient,所以我们初始化queryClient,因为默认是重试三次,这意味着如果想测试错误的查询,测试可能会超时。所以可以在初始化时关闭 const createWrapper () > {const queryClient new…...
软件设计师CISC与RISC考点分析——求三连
一、考点分值占比与趋势分析(CISC与RISC) 综合知识分值统计表 年份考题数量分值分值占比考察重点2018111.33%指令特征对比2019111.33%控制器实现方式2020222.67%寄存器数量/流水线技术2021111.33%寻址方式对比2022222.67%指令复杂度/译码方式2023111.3…...
GO语言(一期)常用关键字总结
GO语言(主题一)常用关键字总结 我们这里列出一些go语言关键字,方便各位友友们检查一下自己的学习效果,也方便友友们学习查询。 break default func interface select case defer go map …...
Ubuntu搭建NFS服务器的方法
0 工具 Ubuntu 18.041 Ubuntu搭建NFS服务器的方法 在Ubuntu下搭建NFS(网络文件系统)服务器可以让我们像访问本地文件一样访问Ubuntu上的文件,例如可以把开发板的根文件系统放到NFS服务器目录下方便调试。 1.1 安装nfs-kernel-server&#…...
京东商品详情API接口开发指南(含Java/Python实现)
接口概述 京东开放平台提供了商品详情查询接口,开发者可以通过SKUID获取商品的详细信息,包括标题、价格、图片、促销信息等。该接口需要申请API权限和认证密钥。 点击获取key和secret 接口特点 支持批量查询(最多20个SKU)返回J…...
二叉树构造:从前序、中序与后序遍历序列入手
目录 引言 从前序与中序遍历序列构造二叉树(题目 105) 解题思路 举例说明 从中序与后序遍历序列构造二叉树(题目 106) 解题思路 举例说明 总结 引言 二叉树的遍历与构造是算法领域中的经典问题。LeetCode 上的“从前序与中…...
GEE谷歌地球引擎批量下载逐日ERA5气象数据的方法
本文介绍在谷歌地球引擎(Google Earth Engine,GEE)中,批量下载逐日的ERA5土壤湿度数据(或者是其他气象数据、遥感影像数据等)的方法。 首先,明确一下本文的需求。我们希望在GEE中,下…...
C#接口(Interface)全方位讲解:定义、特性、应用与实践
引言 在面向对象编程(OOP)中,接口(Interface)是一种重要的结构,它定义了某一类对象或类应遵循的行为规范。接口强调“做什么(What)”,而非“怎么做(How&…...
索引与数据结构、并行算法
3. 索引与数据结构 索引类比目录:类似于书籍目录,帮助我们快速定位信息。索引的核心目的:提升数据查找效率,优化增删改查性能。实际应用广泛:MySQL、Redis、搜索引擎、分布式系统、中间件等。 3.1. 索引设计中的需求…...
GC全场景分析
GC全场景分析 文章目录 GC全场景分析标记-清除法**标记 - 清除法核心流程与 STW 机制****标记 - 清除法四步流程****1. STW 启动(暂停用户线程)****2. 标记可达对象(从根集合出发)****3. 清除未标记对象(回收堆内存&am…...
OSI七层模型和TCP/IP的五层(四层模型)
分层 1.什么是分层 我理解是对同一相同或者相似的事务或者操作功能进行分类,比如我们去餐厅吃饭,就可以分为好多层,客户层,服务员层,前台层,后厨层,每一层都专注自己的事情,客户层…...
MouseDown,MouseUp,LostMouseCapture的先后顺序
本文目标是实现如下功能: 按下一个按钮后置位某变量;鼠标松开后复位某个变量? 看似简单,但是一般来说会存在如下两种现象: 鼠标移出按钮:默认会丢失鼠标事件跟踪,即MouseLeftButtonUp事件并不会被触发。 焦点切换:Tab 键切换焦点会干扰按钮的事件捕获 本文通过几个…...
第8章 常用实用类
8.1 String类 在java.lang包(默认引入)中,可直接使用。 定义为final类,不能扩展String类,不可以继承,不可以有子类。 8.1.1 构造String对象 常量对象: 英文双引号括起来 String常量放入常…...
视差场(disparity field)
视差场(disparity field)是立体视觉中的一个重要概念,用于描述两幅立体图像之间像素的对应关系。以下是对视差场的详细解释: 1. 视差(Disparity)的定义 视差是指同一场景点在两幅立体图像中的像素位置差异…...
AI:OpenAI论坛分享—《AI重塑未来:技术、经济与战略》
AI:OpenAI论坛分享—《AI重塑未来:技术、经济与战略》 导读:2025年4月24日,OpenAI论坛全面探讨了 AI 的发展趋势、技术范式、地缘政治影响以及对经济和社会的广泛影响。强调了 AI 的通用性、可扩展性和高级推理能力,以…...
【已经解决诸多问题】Mamba安装
mamba被称为新一代的计算架构,因此在CV和时序领域存在诸多的方案开始采用这一新架构,但是这个架构的安装过程中存在诸多问题!!!!为了更好帮助大家理解我们给出一个统一的安装流程!!&…...
计算机的基本组成与性能
1. 冯诺依曼体系结构:计算机组成的金字塔 1.1. 计算机的基本硬件组成 1.CPU - 中央处理器(Central Processing Unit)。 2.内存(Memory)。 3.主板(Motherboard)。主板的芯片组(Ch…...
“绿色邮政,智能九识”——呼和浩特邮政无人快递车发车,驶向智慧物流新时代!
5月12日,“绿色邮政,智能九识”呼和浩特邮政无人驾驶快递车发车。 此次投运的邮政无人驾驶快递车实力惊人:单车运量超1000件,时速达40公里,通过智能路径规划实现24小时作业,与传统运输相比,运转…...
AGI大模型(24):通过LangChain的接口来调用OpenAI对话
1 创建对话 使用langchain库中的ChatOpenAI类来创建一个对话模型。 from dotenv import load_dotenvload_dotenv()import os from langchain_openai import ChatOpenAIllm = ChatOpenAI(api_key=os.getenv("DEEPSEEK_API_KEY"),base_url="https://api.deepsee…...
大模型中的Token机制深度解析
目录 大模型中的Token机制深度解析 一、Token的本质与核心作用 二、主流分词算法对比 三、GPT-3分词机制详解 四、分词策略对模型性能的影响 五、工程实践建议 六、未来演进方向 一、Token的本质与核心作用 Token是大模型处理文本的最小语义单元,类似于人类语…...
【MySQL】库与表的操作
一、库的操作 1. 查看数据库 语法:show databases;这里的database是要加s的 查看当前自己所处的数据库:select database(); 例如下图,我当前所处的数据库就是在class1数据库 2. 创建数据库 语法:create database [if not e…...
创建指定版本的vite项目
1、获取vite的版本号 npm view create-vite versions 注:4.4.1版本即对应着node16版本的项目 2、创建制定版本的vite项目 npm init vite<version>...
java中的Servlet3.x详解
Servlet 3.x 是 Java Web 开发的重要里程碑,包含 Servlet 3.0(2009年发布)和 Servlet 3.1(2013年发布)两个主要版本。它通过多项革新优化了开发效率、性能及扩展性,成为现代 Java Web 应用的核心技术基础。…...
单目测距和双目测距 bev 3D车道线
单目视觉测距原理 单目视觉测距有两种方式。 第一种,是通过深度神经网络来预测深度,这需要大量的训练数据。训练后的单目视觉摄像头可以认识道路上最典型的参与者——人、汽车、卡车、摩托车,或是其他障碍物(雪糕桶之类…...
weibo_comment_pc_tool | 我于2025.5月用python开发的评论采集软件,根据帖子链接爬取评论的界面工具
本工具仅限学术交流使用,严格遵循相关法律法规,符合平台内容的合法及合规性,禁止用于任何商业用途! 一、背景分析 1.1 开发背景 微博(以下简称wb)是国内极具影响力的社交媒体平台,具有内容形式…...
ubuntu防火墙命令和放行ssh端口
一、关闭UFW防火墙(Ubuntu默认工具) 1. 临时关闭防火墙 sudo ufw disable sudo ufw status # 显示 Status: inactive 表示已关闭 2. 永久禁用防火墙(禁用系统服务) sudo systemctl stop ufw # 立即停止服务 sudo sy…...
PWM讲解+STM32任意频率、占空比、脉宽生成函数介绍
1.PWM讲解 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制。 脉宽调制 最开始使用PWM时,是做智能车时使用的舵机打角,电机驱动。这都属于比较浅显,普通的应用。下面和大家简单分享一下PWM的…...
C++23 范围迭代器作为非范围算法的输入 (P2408R5)
文章目录 一、引言二、C23及范围迭代器的背景知识2.1 C23概述2.2 范围迭代器的概念 三、P2408R5提案的内容3.1 提案背景3.2 提案内容 四、范围迭代器作为非范围算法输入的优势4.1 代码简洁性4.2 提高开发效率4.3 更好的兼容性 五、具体的代码示例5.1 使用范围迭代器进行并行计算…...
CVE-2018-1273 漏洞深度分析
漏洞概述 CVE-2018-1273 是 Spring Data Commons 中的一个高危远程代码执行(RCE)漏洞,影响版本为 Spring Data Commons 1.13–1.13.10 和 2.0–2.0.5。攻击者通过构造包含恶意 SpEL表达式的 HTTP 请求参数,触发表达式注入&#x…...
C++23:修正常量迭代器、哨兵和范围
文章目录 引言C20范围库回顾C23之前常量迭代器的问题视图可能不传播const代理对象的复杂性泛型代码中的一致性 P2278R4提案及C23的改进std::views::as_const的工作原理代码示例 浅const视图(如std::span)的改进总结 引言 在C的发展历程中,每…...
【漫话机器学习系列】266.雅可比矩阵(Jacobian Matrix)
雅可比矩阵(Jacobian Matrix)详解 | 多变量函数微积分的基石 在深度学习、计算图、优化算法、机器人控制、流形学习等众多领域中,“雅可比矩阵(Jacobian Matrix)”是一个非常核心的数学工具。 这篇文章将结合一张视觉…...
Leetcode 3551. Minimum Swaps to Sort by Digit Sum
Leetcode 3551. Minimum Swaps to Sort by Digit Sum 1. 解题思路2. 代码实现 题目链接:3551. Minimum Swaps to Sort by Digit Sum 1. 解题思路 这一题思路上我实现的非常暴力,就是先求出正确的排列,然后从头考察每一个元素是否处在其目标…...
西门子1200/1500博图(TIA Portal)寻址方式详解
西门子博图(TIA Portal)是西门子公司推出的自动化工程软件平台,广泛应用于工业自动化领域。在编写PLC程序时,寻址方式是一个非常重要的概念,它决定了如何访问和操作PLC中的数据和资源。本文将详细介绍西门子博图中的寻…...