MySQL 存储过程(超详细)

一、什么是存储过程?

  • 存储过程可称为过程化SQL语言,是在普通SQL语句的基础上增加了编程语言的特点,把数据操作语句(DML)和查询语句(DQL)组织在过程化代码中,通过逻辑判断、循环等操作实现复杂计算的程序语言。
  • 换句话说,存储过程其实就是数据库内置的一种编程语言,这种编程语言也有自己的变量、if语句、循环语句等。在一个存储过程中可以将多条SQL语句以逻辑代码的方式将其串联起来,执行这个存储过程就是将这些SQL语句按照一定的逻辑去执行,所以一个存储过程也可以看做是一组为了完成特定功能的SQL 语句集
  • 每一个存储过程都是一个数据库对象,就像table和view一样,存储在数据库当中,一次编译永久有效。并且每一个存储过程都有自己的名字。客户端程序(Java程序)通过存储过程的名字来调用存储过程。
  • 在数据量特别庞大的情况下利用存储过程能达到倍速的效率提升

二、存储过程的优点和缺点?

优点:速度快。

  • 降低了应用服务器(Java程序)数据库服务器之间网络通讯的开销。尤其在数据量庞大的情况下效果显著。

缺点:移植性差。编写难度大。维护性差。

  • 每一个数据库都有自己的存储过程的语法规则,这种语法规则不是通用的。一旦使用了存储过程,则数据库产品很难更换,例如:编写了mysql的存储过程,这段代码只能在mysql中运行,无法在oracle数据库中运行。
  • 对于数据库存储过程这种语法来说,没有专业的IDE工具(集成开发环境),所以编码速度较低。自然维护的成本也会较高。

在实际开发中,存储过程还是很少使用的。只有在系统遇到了性能瓶颈,在进行优化的时候,对于大数量的应用来说,可以考虑使用一些。

三、第一个存储过程

3.1 存储过程的创建

create procedure p1()
beginselect empno,ename from emp;
end;

3.2 存储过程的调用

call p1();

3.3 存储过程的查看

查看创建存储过程的语句:

show create procedure p1;

image.png

通过系统表information_schema.ROUTINES查看存储过程的详细信:information_schema.ROUTINES 是 MySQL 数据库中一个系统表,存储了所有存储过程、函数、触发器的详细信息,包括名称、返回值类型、参数、创建时间、修改时间等。

select * from information_schema.routines where routine_name = 'p1';

image.png

information_schema.ROUTINES 表中的一些重要的列包括:

  • SPECIFIC_NAME:存储过程的具体名称,包括该存储过程的名字,参数列表。
  • ROUTINE_SCHEMA:存储过程所在的数据库名称。
  • ROUTINE_NAME:存储过程的名称。
  • ROUTINE_TYPE:PROCEDURE表示是一个存储过程,FUNCTION表示是一个函数。
  • ROUTINE_DEFINITION:存储过程的定义语句。
  • CREATED:存储过程的创建时间。
  • LAST_ALTERED:存储过程的最后修改时间。
  • DATA_TYPE:存储过程的返回值类型、参数类型等。

3.4 存储过程的删除

drop procedure if exists p1;

四、MySQL的变量

mysql中的变量包括:系统变量用户变量局部变量

4.1 系统变量

  • MySQL 系统变量是指在 MySQL 服务器运行时控制其行为的参数。这些变量可以被设置为特定的值来改变服务器的默认设置,以满足不同的需求。
  • MySQL 系统变量可以具有全局(global)会话(session)作用域。
  • 全局作用域是指对所有连接和所有数据库都适用;
  • 会话作用域是指只对当前连接和当前数据库适用。

查看系统变量

show [global|session] variables;show [global|session] variables like '';select @@[global|session.]系统变量名;

注意:没有指定session或global时,默认是session

设置系统变量

set [global | session] 系统变量名 =;set @@[global | session.]系统变量名 =;

注意:无论是全局设置还是会话设置,当mysql服务重启之后,之前配置都会失效。可以通过修改MySQL根目录下的my.ini配置文件达到永久修改的效果。(my.ini是MySQL数据库默认的系统级配置文件,默认是不存在的,需要新建,并参考一些资料进行配置。)

windows系统是my.ini、 linux系统是my.cnf, my.ini文件通常放在mysql安装的根目录下,如下图:
image.png

这个文件通常是不存在的,可以新建,新建后例如提供以下配置:

[mysqld]
autocommit=0

这种配置就表示永久性关闭自动提交机制。(不建议这样做。)

4.2 用户变量

用户自定义的变量。只在当前会话有效。所有的用户变量'@'开始。

给用户变量赋值

set @name = 'jackson';// 静态赋值
set @age := 30;
set @gender := '男', @addr := '北京大兴区';
select @email := 'jackson@123.com';
select sal into @sal from emp where ename ='SMITH'; // 动态赋值

读取用户变量的值

select @name, @age, @gender, @addr, @email, @sal;

注意:mysql中变量不需要声明。直接赋值就行。如果没有声明变量,直接读取该变量,返回null

4.3 局部变量

在存储过程中可以使用局部变量。使用declare声明。在begin和end之间有效。

变量的声明

declare 变量名 数据类型 [default ...];

变量的数据类型就是表字段的数据类型,例如:int、bigint、char、varchar、date、time、datetime等。
注意:declare通常出现在begin end之间的开始部分

变量的赋值

set 变量名 =;
set 变量名 :=;
select 字段名 into 变量名 from 表名 ...;

案例:以下程序演示局部变量的声明、赋值、读取:

create PROCEDURE p2()
begin /*声明变量*/declare emp_count int default 0;/*声明变量*/declare sal double(10,2) default 0.0;/*给变量赋值*/select count(*) into emp_count from emp;/*给变量赋值*/set sal := 5000.0;/*读取变量的值*/select emp_count;/*读取变量的值*/select sal;
end;
call p2();

五、if语句

5.1 语法格式:

if 条件 then
......
elseif 条件 then
......
elseif 条件 then
......
else
......
end if;

案例:员工月薪sal,超过10000的属于“高收入”,6000到10000的属于“中收入”,少于6000的属于“低收入”。

create procedure p3(               )
begindeclare sal int default 5000;declare grade varchar(20);if sal > 10000 thenset grade := '高收入';elseif sal >= 6000 thenset grade := '中收入';elseset grade := '低收入';end if;select grade;
end;
call p3();

六、参数

存储过程的参数包括三种形式:

  • in:入参(未指定时,默认是in)
  • out:出参
  • inout:既是入参,又是出参

案例:员工月薪sal,超过10000的属于“高收入”,6000到10000的属于“中收入”,少于6000的属于“低收入”。

create procedure p4(in sal int, out grade varchar(20))
beginif sal > 10000 thenset grade := '高收入';elseif sal >= 6000 thenset grade := '中收入';elseset grade := '低收入';end if;
end;
call p4(5000, @grade);
select @grade;

案例:将传入的工资sal上调10%

create procedure p5(inout sal int)
beginset sal := sal * 1.1;
end;
set @sal := 10000;
call p5(@sal);
select @sal;

七、case语句

7.1 语法格式:

casewhen1 then......when2 then......when3 then......else......
end case;
casewhen 条件1 then......when 条件2 then......when 条件3 then......else......
end case;

案例:根据不同月份,输出不同的季节。3 4 5月份春季。6 7 8月份夏季。9 10 11月份秋季。12 1 2 冬季。其他非法。

create procedure mypro(in month int, out result varchar(100))
begin case monthwhen 3 then set result := '春季';when 4 then set result := '春季';when 5 then set result := '春季';when 6 then set result := '夏季';when 7 then set result := '夏季';when 8 then set result := '夏季';when 9 then set result := '秋季';when 10 then set result := '秋季';when 11 then set result := '秋季';when 12 then set result := '冬季';when 1 then set result := '冬季';when 2 then set result := '冬季';else set result := '非法月份';end case;
end;
create procedure mypro(in month int, out result varchar(100))
begin case when month = 3 or month = 4 or month = 5 then set result := '春季';when  month = 6 or month = 7 or month = 8  then set result := '夏季';when  month = 9 or month = 10 or month = 11  then set result := '秋季';when  month = 12 or month = 1 or month = 2  then set result := '冬季';else set result := '非法月份';end case;
end;
call mypro(9, @season);
select @season;

八、while循环

8.1 语法格式:

while 条件 do循环体;
end while;

案例:传入一个数字n,计算1~n中所有偶数的和。

create procedure mypro(in n int)
begindeclare sum int default 0;while n > 0 doif n % 2 = 0 thenset sum := sum + n;end if;set n := n - 1;end while;select sum;
end;
call mypro(10);

九、repeat循环

9.1 语法格式:

repeat循环体;until 条件
end repeat;

注意:条件成立时结束循环

案例:传入一个数字n,计算1~n中所有偶数的和。

create procedure mypro(in n int, out sum int)
begin set sum := 0;repeat if n % 2 = 0 then set sum := sum + n;end if;set n := n - 1;until n <= 0end repeat;
end;
call mypro(10, @sum);
select @sum;

十、loop循环

10.1 语法格式:

  • leave 类似break作用
  • iterate 类似continue作用
create procedure mypro()
begin declare i int default 0;mylp:loop set i := i + 1;if i = 5 then leave mylp;-- 类似break作用end if;select i;end loop;
end;
create procedure mypro()
begin declare i int default 0;mylp:loop set i := i + 1;if i = 5 then iterate mylp;-- 类似continue作用end if;if i = 10 then leave mylp;end if;select i;end loop;
end;

十一、游标cursor

游标(cursor)可以理解为一个指向结果集中某条记录的指针,允许程序逐一访问结果集中的每条记录,并对其进行逐行操作和处理。

使用游标时,需要在存储过程或函数中定义一个游标变量,并通过 DECLARE 语句进行声明和初始化。然后,使用 OPEN 语句打开游标,使用 FETCH 语句逐行获取游标指向的记录,并进行处理。最后,使用 CLOSE 语句关闭游标,释放相关资源。游标可以大大地提高数据库查询的灵活性和效率。

声明游标的语法:

declare 游标名称 cursor for 查询语句;

打开游标的语法:

open 游标名称;

通过游标取数据的语法:

fetch 游标名称 into 变量[,变量,变量......]

关闭游标的语法:

close 游标名称;

案例:从dept表查询部门编号和部门名,创建一张新表dept2,将查询结果插入到新表中。

drop procedure if exists mypro;create procedure mypro()
begin declare no int;declare name varchar(100);declare dept_cursor cursor for select deptno,dname from dept;drop table if exists dept2;create table dept2(no int primary key,name varchar(100));open dept_cursor;while true dofetch dept_cursor into no, name;insert into dept2(no,name) values(no,name);end while;close dept_cursor;
end;call mypro();

执行结果:

在这里插入图片描述

出现了异常:异常信息中显示没有数据了。这是因为while true循环导致的。

不过虽然出现了异常,但是表创建成功了,数据也插入成功了:

在这里插入图片描述

注意:声明局部变量和声明游标有顺序要求,局部变量的声明需要在游标声明之前完成。

十二、捕捉异常并处理

12.1 语法格式:

DECLARE handler_name HANDLER FOR condition_value action_statement
  1. handler_name 表示异常处理程序的名称,重要取值包括:
    1. CONTINUE:发生异常后,程序不会终止,会正常执行后续的过程。(捕捉)
    2. EXIT:发生异常后,终止存储过程的执行。(上抛)
  2. condition_value 是指捕获的异常,重要取值包括:
    1. SQLSTATE sqlstate_value,例如:SQLSTATE ‘02000’
    2. SQLWARNING,代表所有01开头的SQLSTATE
    3. NOT FOUND,代表所有02开头的SQLSTATE
    4. SQLEXCEPTION,代表除了01和02开头的所有SQLSTATE
  3. action_statement 是指异常发生时执行的语句,例如:CLOSE cursor_name

给之前的游标添加异常处理机制:

drop procedure if exists mypro;create procedure mypro()
begin declare no int;declare name varchar(100);declare dept_cursor cursor for select deptno,dname from dept;declare exit handler for not found close dept_cursor;drop table if exists dept2;create table dept2(no int primary key,name varchar(100));open dept_cursor;while true dofetch dept_cursor into no, name;insert into dept2(no,name) values(no,name);end while;close dept_cursor;
end;call mypro();

十三、存储函数

存储函数:带返回值存储过程。参数只允许是in(但不能写显示的写in)。没有out,也没有inout。

13.1 语法格式:

CREATE FUNCTION 存储函数名称(参数列表) RETURNS 数据类型 [特征]
BEGIN--函数体RETURN ...;
END;

“特征”的可取重要值如下:

  • deterministic:用该特征标记该函数为确定性函数(什么是确定性函数?每次调用函数时传同一个参数的时候,返回值都是固定的)。这是一种优化策略,这种情况下整个函数体的执行就会省略了,直接返回之前缓存的结果,来提高函数的执行效率。
  • no sql:用该特征标记该函数执行过程中不会查询数据库,如果确实没有查询语句建议使用。告诉 MySQL 优化器不需要考虑使用查询缓存和优化器缓存来优化这个函数,这样就可以避免不必要的查询消耗产生,从而提高性能。
  • reads sql data:用该特征标记该函数会进行查询操作,告诉 MySQL 优化器这个函数需要查询数据库的数据,可以使用查询缓存来缓存结果,从而提高查询性能;同时 MySQL 还会针对该函数的查询进行优化器缓存处理。

案例:计算1~n的所有偶数之和

-- 删除函数
drop function if exists sum_fun;-- 创建函数
create function sum_fun(n int)
returns int deterministic 
begin declare result int default 0;while n > 0 do if n % 2 = 0 then set result := result + n;end if;set n := n - 1;end while;return result;
end;-- 调用函数
set @result = sum_fun(100);
select @result;

十四、触发器

MySQL 触发器是一种数据库对象,它是与表相关联的特殊程序。它可以在特定的数据操作(例如插入(INSERT)、更新(UPDATE)或删除(DELETE))触发时自动执行。MySQL 触发器使数据库开发人员能够在数据的不同状态之间维护一致性和完整性,并且可以为特定的数据库表自动执行操作。

触发器的作用主要有以下几个方面:

  1. 强制实施业务规则:触发器可以帮助确保数据表中的业务规则得到强制执行,例如检查插入或更新的数据是否符合某些规则。
  2. 数据审计:触发器可以声明在执行数据修改时自动记日志或审计数据变化的操作,使数据对数据库管理员和 SQL 审计人员更易于追踪和审计。
  3. 执行特定业务操作:触发器可以自动执行特定的业务操作,例如计算数据行的总数、计算平均值或总和等。

MySQL 触发器分为两种类型: BEFOREAFTER

  • BEFORE 触发器在执行 INSERT、UPDATE、DELETE 语句之前执行
  • AFTER 触发器在执行 INSERT、UPDATE、DELETE 语句之后执行。

创建触发器的语法如下:

CREATE TRIGGER trigger_name
BEFORE/AFTER INSERT/UPDATE/DELETE ON table_name FOR EACH ROW
BEGIN
-- 触发器执行的 SQL 语句
END;

其中:

  • trigger_name:触发器的名称
  • BEFORE/AFTER:触发器的类型,可以是 BEFORE 或者 AFTER
  • INSERT/UPDATE/DELETE:触发器所监控的 DML 调用类型
  • table_name:触发器所绑定的表名
  • FOR EACH ROW:表示触发器在每行受到 DML 的影响之后都会执行
  • 触发器执行的 SQL 语句:该语句会在触发器被触发时执行

需要注意的是,触发器是一种高级的数据库功能,只有在必要的情况下才应该使用,例如在需要实施强制性业务规则时。过多的触发器和复杂的触发器逻辑可能会影响查询性能和扩展性。

关于触发器的NEW和OLD关键字:

在 MySQL 触发器中,NEWOLD 是两个特殊的关键字,用于引用在触发器中受到修改的行的新值旧值。具体而言:

  • NEW:在触发 INSERT 或 UPDATE 操作期间,NEW 用于引用将要插入或更新到表中的新行的值。
  • OLD:在触发 UPDATE 或 DELETE 操作期间,OLD 用于引用更新或删除之前在表中的旧行的值。

通俗的讲,NEW 是指触发器执行的操作所要插入或更新到当前行中的新数据;而 OLD 则是指当前行在触发器执行前原本的数据。

在MySQL 触发器中,NEW 和 OLD 使用方法是相似的。在触发器中,可以像引用表的其他列一样引用 NEW 和 OLD。例如,可以使用 OLD.column_name 从旧行中引用列值,也可以使用 NEW.column_name 从新行中引用列值。

示例:

假设有一个名为 my_table 的表,其中包含一个名为 quantity 的列。当在该表上执行 UPDATE 操作时,以下触发器会将旧值 OLD.quantity 累加到新值 NEW.quantity 中:

CREATE TRIGGER my_trigger
BEFORE UPDATE ON my_table
FOR EACH ROW
BEGIN
SET NEW.quantity = NEW.quantity + OLD.quantity;
END;

在此触发器中,OLD.quantity 引用原始行的 quantity 值(旧值),而 NEW.quantity 引用更新行的 quantity 值(新值)。在触发器执行期间,数据行的 quantity 值将设置为旧值加上新值。

案例:当我们对dept表中的数据进行insert delete update的时候,请将这些操作记录到日志表当中,日志表如下:

drop table if exists oper_log;create table oper_log(id bigint primary key auto_increment,table_name varchar(100) not null comment '操作的哪张表',oper_type varchar(100) not null comment '操作类型包括insert delete update',oper_time datetime not null comment '操作时间',oper_id bigint not null comment '操作的那行记录的id',oper_desc text comment '操作描述'
);

触发器1:向dept表中插入数据时,记录日志

create trigger dept_trigger_insert 
after insert on dept
for each row
begininsert into oper_log(id,table_name,oper_type,oper_time,oper_id,oper_desc) values
(null,'dept','insert',now(),new.deptno,concat('插入数据:deptno=', new.deptno, ',dname=', new.dname,',loc=', new.loc));
end;

查看触发器:

show triggers;

删除触发器:

drop trigger if exists dept_trigger_insert;

向dept表中插入一条记录:
image.png
日志表中多了一条记录:
image.png

触发器2:修改dept表中数据时,记录日志

create trigger dept_trigger_update
after update on dept
for each row
begininsert into oper_log(id,table_name,oper_type,oper_time,oper_id,oper_desc) values
(null,'dept','update',now(),new.deptno,concat('更新前:deptno=', old.deptno, ',dname=', old.dname,',loc=', old.loc, ',更新后:deptno=', new.deptno, ',dname=', new.dname,',loc=', new.loc));
end;

更新一条记录:

update dept set loc = '北京' where deptno = 60;

日志表中多了一条记录:
image.png
注意:更新一条记录则对应一条日志。如果一次更新3条记录,那么日志表中插入3条记录。

触发器3:删除dept表中数据时,记录日志

create trigger dept_trigger_delete
after delete on dept
for each row
begininsert into oper_log(id,table_name,oper_type,oper_time,oper_id,oper_desc) values
(null,'dept','delete',now(),old.deptno,concat('删除了数据:deptno=', old.deptno, ',dname=', old.dname,',loc=', old.loc));
end;

删除一条记录:

delete from dept where deptno = 60;

日志表中多了一条记录:

image.png

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

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

相关文章

K倍区间(蓝桥杯)

文章目录 K倍区间题目描述前缀和数学优化代码部分解释 K倍区间 题目描述 给定一个长度为 N的数列&#xff0c;A1,A2,…AN&#xff0c;如果其中一段连续的子序列 Ai,Ai1,…Aj 之和是 K的倍数&#xff0c;我们就称这个区间 [i,j]是 K倍区间。 你能求出数列中总共有多少个 K倍区…

上海雷卯可以解决YPbPr/ YCbCr接口 ESD/EOS静电浪涌问题

YPbPr /YCbCr 接口传输的是视频信号&#xff0c;不传输音频信号。YPbPr 和 YCbCr 都是视频信号的颜色编码格式&#xff0c;多应用于机顶盒&#xff08;Set-top box&#xff09;,TV电视&#xff0c;投影仪&#xff0c;游戏机和DVD播放器。 YPbPr&#xff1a;是一种模拟视频接口…

05-调用API

上一篇&#xff1a; 04-JNI函数 调用 API 允许软件供应商将 Java VM 加载到任意本地应用程序中。供应商可以提供支持 Java 的应用程序&#xff0c;而无需链接 Java VM 源代码。 5.1 概述 下面的代码示例说明了如何使用调用 API 中的函数。在这个示例中&#xff0c;C 代码创建了…

Discuz论坛网站报错Discuz!Database Error(0)notconnect的解决办法

运营服务器大本营有段时间了&#xff0c;在运营期间遇到两次Discuz&#xff01;Database Error&#xff08;0&#xff09;notconnect报错&#xff0c;和你们分享遇到Discuz报错的解决办法&#xff0c;希望可以帮助到你。 首先网站报错&#xff08;0&#xff09;notconnect&…

【Web】浅聊Java反序列化之C3P0——JNDI注入利用

目录 简介 原理分析 EXP 前文&#xff1a;【Web】浅聊Java反序列化之C3P0——URLClassLoader利用 【Web】浅聊Java反序列化之C3P0——不出网Hex字节码加载利用 简介 出网的情况下&#xff0c;这个C3P0的Gadget可以和fastjson&#xff0c;Snake YAML , JYAML,Yamlbeans , …

如何防御udp攻击

UDP Flood是互联网上最经典的DDoS&#xff08;Distributed Denial of Service&#xff09;攻击之一。攻击者在短时间内向目标设备发送大量的UDP报文&#xff0c;导致链路拥塞甚至网络瘫痪。一般的UDP报文由攻击工具伪造&#xff0c;通常在数据段具备相同的特征&#xff0c;另一…

【嵌入式高级C语言】9:万能型链表懒人手册

文章目录 序言单向不循环链表拼图框架搭建 - Necessary功能拼图块1 创建链表头信息结构体 - Necessary2 链表头部插入 - Optional3 链表的遍历 - Optional4 链表的销毁 - Necessary5 链表头信息结构体销毁 - Necessary6 获取链表中节点的个数 - Optional7 链表尾部插入 - Optio…

网站开发之旅:从概念到实现

在我成为一名专业的网站开发者的过程中&#xff0c;我有幸参与了多个激动人心的项目。其中&#xff0c;一个我印象尤为深刻的经历是&#xff0c;开发一个名为“文案推荐网”的主题网站&#xff08;www.zimeiti.love&#xff09;。这个项目不仅让我深入了解了网站开发的各个方面…

excel常用操作备忘

目录 快捷键基础数据透视图统计某列的值出现的频数 数据有效性数据分列运算符顺序文本匹配中的通配符错误的类型&#xff08;常与IF嵌套使用&#xff09;函数RANK(num, ref, [order])MID(str, start, len)逻辑函数混合函数选取整列AVERAGEIF(range, criteria, average_range)TR…

【软件测试面试】银行项目测试面试题+答案(一)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 面试题&#xff1…

Unity类银河恶魔城学习记录9-2 P83 Explosive crystal源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Crystal_Skill_Controller using System.Collections; using System.Colle…

【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用

目录 一、Linux编译器-gcc/g1.1 gcc/g 使用方法1.2 程序的翻译过程1.3 链接 -- 动静态链接特点及区别 二、Linux调试器-gdb2.1 背景2.2 使用方法 三、Linux项目自动化构建工具-make/Makefile3.1 背景3.2 原理3.3 项目清理 一、Linux编译器-gcc/g 1.1 gcc/g 使用方法 格式&…

如何在Windows系统部署Jellyfin Server并实现公网访问内网影音文件

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及&#xff0c;各种各样的使用需求也被开发出来&…

用BIO实现tomcat

一、前言 本课程的难度较高&#xff0c;需要将Servlet原理和IO课程全部学完。 二、当前项目使用方式 (1).自定义servlet 自定义servlet需要实现WebServlet并且实现name和urlMapping 重启进行访问 http://localhost:8090/myServlet (2).自定义html 重启进行访问 http://loc…

项目的搭建与配置

vue create calendar_pro 选择如下配置选项 安装 vue3 支持 vue add vue-next package.json 关闭 eslint 检测。 vue.config.js 配置跨域同源策略。 const { defineConfig } require(vue/cli-service) module.exports defineConfig({transpileDependencies: true,devServe…

微服务:Docker篇

1. 初识Docker 1.1. 什么是Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。 在数百上千台服务中重复部署&#xff0c;环境不一定一…

【计网】TCP协议安全与风险:深入探讨网络通信的基石

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Linux ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 &#x1f310;前言 &#x1f512;正文 TCP (Transmission Control Protocol): UDP (User Datagram Protocol): HTTP (Hypertext Transfer …

git fatal: detected dubious ownership in repository at ‘xxx‘ 彻底解决方法

前言 在 windows 重置后&#xff0c; git 仓库无法正常使用 git 的所有 命令&#xff0c;运行任何 git 命令&#xff0c;都会提示如下&#xff1a; $ git log fatal: detected dubious ownership in repository at D:/rk/rk3568/nanopi/uboot-rockchip D:/rk/rk3568/nanopi/u…

Linux学习之线程

目录 线程概念 1.什么是线程&#xff1f; 2.线程的优缺点 3.线程异常 4.线程用途 线程操作 1.如何给线程传参 2.线程终止 3.获取返回值 4.分离状态 5.退出线程 线程的用户级地址空间&#xff1a; 线程的局部存储 线程的同步与互斥 互斥量mutex 数据不一致的主要过…

编译随笔(一)makefile基础知识

编译随笔系列文章目录 1. makefile基础知识 文章目录 编译随笔系列文章目录前言参考资料前置知识交叉编译链程序编译预处理&#xff08;Preprpcessing&#xff09;编译&#xff08;Compilation&#xff09;汇编&#xff08;Assemble&#xff09;链接&#xff08;Linking&#…