MySQL学习(存储过程)

news2024/9/21 23:31:10

文章目录

  • 存储过程
    • 基本概念
    • 变量定义
    • 参数传递
      • in: 传入参数
      • out:传出参数
      • inout:传入传出参数
    • 流程控制
      • if-else
      • case: 类似Switch
      • 循环
    • 游标(cursor)
    • 异常处理
    • 存储过程练习
  • 存储函数
  • 触发器

存储过程

基本概念

  • 存储过程就是一组SQL语句集,实现一些比较复杂的逻辑功能,存储过程在数据库中创建,在其他程序中调用。
  • 存储过程就是数据库SQL语言层面的代码封装,可以重复调用。
  • 特性
  1. 有输入输出参数,参数可以有默认值,可以声明变量。
  2. 有一些控制语句,比如if、while等。通过编写存储过程,可以完成一些复杂的SQL逻辑操作。
  3. 模块化、封装、代码复用。
  4. 执行速度快,因为存储过程在创建时就已经编译和优化过,执行效率高。
  • 语法:
delimiter 自定义结束符号
create procedure 存储过程名( in|out 参数名 数据类型, ...)
begin
    SQL语句
end 自定义结束符号
delimiter ; -> 恢复默认结束符号';'
  • 创建存储过程
delimiter $$

create procedure p1()
begin
    select a.ename, a.empno from emp a;
end $$
delimiter ;
  • 删除存储过程
drop procedure if exists p1;
  • 调用存储过程
call p1();

变量定义

/*
局部变量: 只在begin...end中有效
    在begin...end中定义,使用declare关键字
    语法:declare var_name 类型 [default value];
用户变量:当前会话(连接)有效
    不需要提前声明
    语法:@var_name
系统变量:分为全局变量和会话变量
    全局变量:在MySQL启动时服务器自动初始化为默认值,默认值可以通过my.ini文件更改
        语法:@@global.var_name
    会话变量:每次建立新的连接的时候,由MySQL将全局变量的值复制给会话变量
        语法:@@session.var_name
    区别:修改全局变量会影响MySQL服务器,而会话变量只会影响当前会话(连接)
    系统变量有的可以利用语句更改,有的是只读的
*/
  • 局部变量
    delimiter $$
    create procedure p2()
    begin
        declare var1 varchar(20) default 'abc'; -- 定义/声明变量
        declare var2 varchar(20);
        set var1 = 'def'; -- 赋值方式1
        select a.ename into var2 from emp a where a.empno = 7369; -- 赋值方式2
        select var1, var2;    -- 输出变量
    end $$
    delimiter ;

    call p2();
  • 用户变量
    delimiter $$
    create procedure p3()
    begin
        set @var1 = 'abc'; -- 定义/声明变量
        select @var1;    -- 输出变量
    end $$
    delimiter ;
    call p3();

    select @var1;   -- 也可以查询到变量
  • 系统变量
        -- 全局变量
        show global variables;  -- 查看全局变量
        select @@global.auto_increment_offset; -- 查看某全局变量
        -- 修改某全局变量的值
            set @@global.auto_increment_offset = 2;
            set global auto_increment_offset = 2;

        -- 会话变量
        show session variables;  -- 查看会话变量
        select @@session.auto_increment_offset; -- 查看某会话变量
        -- 修改某会话变量的值
            set @@session.auto_increment_offset = 2;
            set session auto_increment_offset = 2;

参数传递

in: 传入参数

  • 传入员工编号,查找员工姓名
        delimiter $$
        create procedure p4(in parameter_empno int)
        begin
            select a.ename, a.empno from emp a where a.empno = parameter_empno;
        end $$
        delimiter ;
        call p4(7900);
  • 传入部门名称和工资,查找该部门中工资高于指定工资的员工
        delimiter $$
        create procedure p5(in parameter_dname varchar(20), in parameter_salary double)
        begin
            select a.ename, b.dname, a.sal
            from emp a, dept b
            where b.dname = parameter_dname and a.sal > parameter_salary and a.deptno = b.deptno;
        end $$
        delimiter ;
        call p5('researach', 1000);

out:传出参数

  • 传入员工编号,传出该员工的名字
        delimiter $$
        create procedure p6(in parameter_empno int, out parameter_ename varchar(20))
        begin
            select a.ename into parameter_ename from emp a where a.empno = parameter_empno;
        end $$
        delimiter ;
        call p6(7902, @var1);
        select @var1;   -- 输出传出参数
  • 传入员工编号,传出该员工的名字和工资
        delimiter $$
        create procedure p7(in parameter_empno int, out parameter_ename varchar(20), out paraneter_sal double)
        begin
            select a.ename, a.sal into parameter_ename, paraneter_sal from emp a where a.empno = parameter_empno;
        end $$
        delimiter ;
        call p7(7902, @var1, @var2);
        select @var1, @var2;   -- 输出传出参数

inout:传入传出参数

从外部传入参数,在存储过程中改变它,最后将结果返回

  • 传入一个数字,传出他的10倍
        delimiter $$
        create procedure p8(inout parameter_num int)
        begin
            set parameter_num = parameter_num * 10;
        end $$
        delimiter ;
        set @var1 = 5;
        call p8(@var1);
        select @var1;   -- 输出
  • 传入员工姓名和工资,将员工的名字拼接部门编号,工资乘以12
        delimiter $$
        create procedure p9(inout parameter_ename varchar(20), inout parameter_sal double)
        begin
            select concat(a.deptno, '-', parameter_ename) into parameter_ename from emp a where a.ename = parameter_ename;
            select parameter_sal * 12 into parameter_sal;
        end $$
        delimiter ;
        set @var1 = 'jack';
        set @var2 = 8000;
        call p9(@var1, @var2);
        select @var1, @var2;   -- 输出

流程控制

if-else

  • 成绩等级
        /*
            输入学生成绩,判断成绩等级
            score < 60: 不及格
            score >= 60 and score < 80: 及格
            score >= 80 and score < 90: 良好
            score >= 90 and score <= 100: 优秀
            score > 100: 成绩错误
        */
        delimiter $$
        create procedure p10(in parameter_score int, out parameter_grade varchar(20))
        begin
            if parameter_score < 60
                then set parameter_grade = '不及格';
            elseif parameter_score >= 60 and parameter_score < 80
                then set parameter_grade = '及格';
            elseif parameter_score >= 80 and parameter_score < 90
                then set parameter_grade = '良好';
            elseif parameter_score >= 90 and parameter_score <= 100
                then set parameter_grade = '优秀';
            else
                set parameter_grade = '成绩错误';
            end if;
        end $$
        delimiter ;
        call p10(85, @var1);
        select @var1;   -- 输出
  • 传入员工姓名,判断该员工的工资等级
        delimiter $$
        create procedure p11(in parameter_ename varchar(20), out parater_sal_level int)
        begin
            declare var_sal, var_losal, var_hisal double;
            select a.sal into var_sal from emp a where a.ename = parameter_ename;

            select b.losal, b.hisal into var_losal, var_hisal from salgrade b where b.grade = 1;
            if var_sal >= var_losal and var_sal <= var_hisal
                then set parater_sal_level = 1;
            end if;

            select c.losal, c.hisal into var_losal, var_hisal from salgrade c where c.grade = 2;
            if var_sal > var_losal and var_sal <= var_hisal
                then set parater_sal_level = 2;
            end if;

            select d.losal, d.hisal into var_losal, var_hisal from salgrade d where d.grade = 3;
            if var_sal > var_losal and var_sal <= var_hisal
                then set parater_sal_level = 3;
            end if;

            select e.losal, e.hisal into var_losal, var_hisal from salgrade e where e.grade = 4;
            if var_sal > var_losal and var_sal <= var_hisal
                then set parater_sal_level = 4;
            end if;

            select f.losal, f.hisal into var_losal, var_hisal from salgrade f where f.grade = 5;
            if var_sal > var_losal and var_sal <= var_hisal
                then set parater_sal_level = 5;
            end if;
        end $$
        delimiter ;

        call p11('jack', @var1);
        select @var1;   -- 输出

case: 类似Switch

        delimiter $$
        create procedure p12(in pay_type int)
        begin
            case pay_type
                when 1 then select '现金支付';
                when 2 then select '银行卡支付';
                when 3 then select '支付宝支付';
                when 4 then select '微信支付';
                else select '其他支付方式';
            end case;
        end $$
        delimiter ;
        call p12(3);   -- 输出

循环

  • 分类:while, loop, repeat
  • 控制:leave类似于break,iterate类似于continue
  • 新建一个表
        create table if not exists user
        (
            uid int,
            username varchar(20),
            password varchar(20)
        );
  • 向表中添加指定条数的数据
  1. while循环
                -- while
                truncate user;  -- 清空表

                delimiter $$
                create procedure p13(in parameter_InsertCount int)
                begin
                    declare i int default 1;
                    while i <= parameter_InsertCount do
                            insert into user(uid, username, password) values(i, concat('user', i), concat('pwd', i));
                            set i = i + 1;
                        end while;
                end $$
                delimiter ;
                call p13(5);

                -- while + leave
                truncate user;  -- 清空表

                delimiter $$
                create procedure p14(in parameter_InsertCount int)
                begin
                    declare i int default 1;
                    label: while 1 do
                            insert into user(uid, username, password) values(i, concat('user', i), concat('pwd', i));
                            if i >= parameter_InsertCount
                                then leave label;
                            end if;
                            set i = i + 1;
                        end while label;
                end $$
                delimiter ;
                call p14(5);
  1. reapeat循环
                truncate user;  -- 清空表

                delimiter $$
                create procedure p15(in parameter_InsertCount int)
                begin
                    declare i int default 1;
                    label: repeat
                        insert into user(uid, username, password) values(i, concat('user', i), concat('pwd', i));
                        set i = i + 1;
                    until i > parameter_InsertCount
                    end repeat label;
                end $$
                delimiter ;
                call p15(5);
  1. loop循环
            truncate user;  -- 清空表
            delimiter $$
            create procedure p16(in parameter_InsertCount int)
            begin
                declare i int default 1;
                label: loop
                    insert into user(uid, username, password) values(i, concat('user', i), concat('pwd', i));
                    set i = i + 1;
                    if i > parameter_InsertCount
                        then leave label;
                    end if;
                end loop label;
            end $$
            delimiter ;
            call p16(5);

游标(cursor)

  • cursor是用来储存查询结果集的数据类型,在存储过程中使用游标可以对结果集中的数据进行循环操作,包括声明、open、fetch和close
  • 语法
/*
语法:
    -- 声明游标:declare cursor_name cursor for select_statement;
    -- 打开游标:open cursor_name;
    -- 获取游标数据:fetch cursor_name into variable [,variable] 。。。;
    -- 关闭游标:close cursor_name;
*/
  • 需求:输入部门名称,查询该部门员工的编号、姓名和工资,将查询结果添加游标,然后逐行输出
	drop procedure if exists p17;   -- 删除存储过程
	delimiter $$
	create procedure p17(in parameter_dname varchar(20))
	begin
	    declare var_empno int;
	    declare var_ename varchar(20);
	    declare var_sal double;
	    -- 声明游标
	    declare my_cursor cursor for
	        select a.empno, a.ename, a.sal
	            from emp a, dept b
	            where a.deptno = b.deptno and b.dname = parameter_dname;
	    -- 打开游标
	    open my_cursor;
	    -- 获取数据
	    label: loop		-- 有正确结果,但是会报错(not found)
	        fetch my_cursor into var_empno, var_ename, var_sal;
	        select var_empno, var_ename, var_sal;
	    end loop label;
	    -- 关闭游标
	    close my_cursor;
	end $$
	delimiter ;
	call p17('sales');

异常处理

在程序中,如果发生错误,则程序会停止执行。为了防止这种情况的发生,可以使用异常处理机制

  • 语法
    /*
        语法:
            -- 声明异常处理:declare handler_type handler
                            for condition_value [,condition_value] ...
                            statement;
            -- 异常处理类型(handler_type):
                -- continue:继续执行
                -- exit:退出执行
                -- undo:撤销事务
            -- 异常处理条件(condition_value):
                -- mysql错误代码
                -- condition_name:异常名称
                    -- sqlwarning:警告
                    -- not found:未找到
                    -- sqlexception:异常
     */
  • 以上个例子为例,使用异常处理loop循环解决报错问题
    – 当遇到not found异常时将标记值flag赋值0,在loop循环中当flag为1时正常获取游标数据,为0时关闭循环并继续执行(continue)后面代码。
        delimiter $$
        create procedure p18(in parameter_dname varchar(20))
        begin
            declare var_empno int;
            declare var_ename varchar(20);
            declare var_sal double;

            -- 定义标记值
            declare flag int default 1;

            -- 声明游标
            declare my_cursor cursor for
                select a.empno, a.ename, a.sal
                    from emp a, dept b
                    where a.deptno = b.deptno and b.dname = parameter_dname;

            -- 定义句柄
            declare continue handler for not found set flag = 0;

            -- 打开游标
            open my_cursor;
            -- 获取数据
            label: loop   -- 正确
                fetch my_cursor into var_empno, var_ename, var_sal;
                if flag = 1 then
                    select var_empno, var_ename, var_sal;
                else
                    leave label;
                end if;
            end loop label;
            -- 关闭游标
            close my_cursor;
        end $$
        delimiter ;
        call p18('sales');

存储过程练习

  • 需求:提前一个月创建该月的所有表(每天一个,表名格式:table_user_2019_07_31)
    create database if not exists procedure_practice;
    use procedure_practice;
    drop procedure if exists proc_test;

    delimiter $$
    create procedure proc_test()
    begin
        declare next_year int;  -- 下一个月的年份
        declare next_month int; -- 下一个月的月份
        declare next_month_day int; -- 下一个月的最后一天

        declare next_month_str varchar(2); -- 下一个月的月份字符串
        declare next_month_day_str varchar(2); -- 下一个月的日期字符串

        -- 每天的表名
        declare table_name_str varchar(50);

        declare t_index int default 1;

        -- 获取下一个月的年份
        set next_year = year(date_add(now(), interval 1 month));
        -- 获取下一个月的月份
        set next_month = month(date_add(now(), interval 1 month));
        -- 获取下一个月的最后一天
        set next_month_day = dayofmonth(last_day(date_add(now(), interval 1 month)));

        if next_month < 10 then
            set next_month_str = concat('0', next_month);
        else
            set next_month_str = concat('', next_month);
        end if;

        while t_index <= next_month_day do

            if t_index < 10 then
                set next_month_day_str = concat('0', t_index);
            else
                set next_month_day_str = concat('', t_index);
            end if;

            -- 拼接表的日期部分名称
            set table_name_str = concat(next_year, '_', next_month_str, '_', next_month_day_str);
            -- 拼接表名
            set table_name_str = concat('table_user_', table_name_str);

            -- 拼接创建表的sql语句
            set @create_table_sql = concat('create table if not exists ', table_name_str, '(uid int, uname varchar(50), information varchar(50)) collate=utf8mb4_general_ci engine=innodb');

            -- from 后面不能使用局部变量
            prepare create_table_stmt from @create_table_sql;   -- 根据存储在变量 @create_table_sql 中的SQL语句创建一个名为 create_table_stmt 的预编译语句。
            execute create_table_stmt;  -- 执行创建表的操作
            deallocate prepare create_table_stmt;   -- 取消准备之前创建的预编译语句,释放相关资源。

            -- 更新t_index
            set t_index = t_index + 1;
        end while;
    end $$
    delimiter ;

    call proc_test();

存储函数

  • 格式
/*
    格式:
    create function 函数名(参数列表) returns 返回值类型
    begin
        函数体
    end;
*/
  • 创建存储函数(无参数)
        drop function if exists my_f1;
        delimiter $$
        create function my_f1() returns int READS SQL DATA
        begin
            declare num int default 0;
            select count(*) into num from emp;
            return num;
        end $$
        delimiter ;

        select my_f1(); -- 调用存储函数
  • 创建存储函数(有参数)
        drop function if exists my_f2;
        delimiter $$
        create function my_f2(id int) returns varchar(20) READS SQL DATA
        begin
            declare name varchar(20);
            select a.ename into name from emp a where a.empno = id;
            return name;
        end $$
        delimiter ;
        select my_f2(7369); -- 调用存储函数

触发器

  • 是特殊的存储过程,不能直接调用,而是由事件触发自动执行
  • 只有执行insert(I), update(U), delete(D)操作时才能触发
  • 协助应用在数据库端确保数据的完整性,日志记录,数据校验等
  • 只支持行级触发,不支持语句级触发
  • 关键字:OLD、NEW, OLD表示修改前的记录,NEW表示修改后的记录
/*
    注意事项:
    1. 触发器不能接受参数
    2. 不能对本表进行insert(I), update(U), delete(D)操作,可能会循环触发
    3. 触发器会降低效率,因为它是针对每一行的操作,对表中的每行记录都会执行一次,所以在增删改频繁的表上不要使用触发器
*/
  • 创建触发器格式
    /*
        格式:
        -- 只有一个执行语句的触发器
        create trigger 触发器名 before|after 触发事件
        on 表名 for each row
        执行语句;

        -- 多个执行语句的触发器
        create trigger 触发器名 before|after 触发事件
        on 表名 for each row
        begin
            执行语句列表
        end;
    */
  • 查看触发器show triggers;
  • 数据准备
        create database if not exists mydb_trigger;
        use mydb_trigger;
        -- 用户表
        create table if not exists user(
            uid int primary key,
            uname varchar(50) not null,
            password varchar(50) not null
        );
        -- 用户信息操作日志表
        create table if not exists user_logs(
            id int primary key auto_increment,
            time timestamp,
            log_next varchar(255)
        );
  • 需求1:user表中插入数据时,将操作日志记录到user_logs表中
            -- 创建触发器
            create trigger tri_user_insert
                after insert on user for each row
                insert into user_logs(time, log_next) values(now(), '有新用户添加');
            -- 插入数据,测试触发器
            insert into user(uid, uname, password) values(1001, 'zhangsan', '<PASSWORD>');
            -- 删除触发器
            drop trigger if exists tri_user_insert;
  • 需求2:user表中更新数据时,将操作日志记录到user_logs表中
            -- 创建触发器
            delimiter $$
            create trigger tri_user_update
                after update on user for each row
                begin
                insert into user_logs(time, log_next) values(now(), '用户信息更新');
                end $$
            delimiter ;
            -- 更新数据,测试触发器
            update user set uname = 'lisi' where uid = 1001;
            -- 删除触发器
            drop trigger if exists tri_user_update;
  • NEW和OLD的使用
  1. insert 类型的触发器
                -- NEW
                create trigger tri_user_insert_new
                    after insert on user for each row
                    insert into user_logs(time, log_next) values(now(), concat('有新用户添加', NEW.uid, NEW.uname, NEW.password));
                insert into user(uid, uname, password) values(1002, 'wangwu', '<PASSWORD2>');

                drop trigger if exists tri_user_insert_new;
  1. update 类型的触发器
                -- OLD
                create trigger tri_user_update_old
                    after update on user for each row
                    insert into user_logs(time, log_next) values(now(), concat_ws(',', '用户信息更新,更新前的信息为:', OLD.uid, OLD.uname, OLD.password));
                update user set uname = 'zhaoliu' where uid = 1002;

                drop trigger if exists tri_user_update_old;
                -- NEW
                create trigger tri_user_update_new
                    after update on user for each row
                    insert into user_logs(time, log_next) values(now(), concat_ws(',', '用户信息更新,更新后的信息为:', NEW.uid, NEW.uname, NEW.password));
                update user set uname = 'lilei' where uid = 1002;

                drop trigger if exists tri_user_update_new;
  1. delete 类型的触发器
                -- OLD
                create trigger tri_user_delete_old
                    after delete on user for each row
                    insert into user_logs(time, log_next) values(now(), concat_ws(',', '用户删除,删除的用户信息为:', OLD.uid, OLD.uname, OLD.password));
                delete from user where uid = 1002;

                drop trigger if exists tri_user_delete_old;

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

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

相关文章

Tomcat服务器—Windows下载配置详细教程

一、关于 1.1 简介 Tomcat是一个开源的Java Servlet容器和Web服务器&#xff0c;由Apache软件基金会维护。它实现了Java Servlet和JavaServer Pages (JSP) 规范&#xff0c;用于运行Java Web应用程序。Tomcat支持多种Java EE功能&#xff0c;并提供了高效的性能和可扩展性&am…

Spring扩展点系列-MergedBeanDefinitionPostProcessor

文章目录 简介源码分析示例示例一&#xff1a;Spring中Autowire注解的依赖注入 简介 spring容器中Bean的生命周期内所有可扩展的点的调用顺序 扩展接口 实现接口ApplicationContextlnitializer initialize AbstractApplicationContext refreshe BeanDefinitionRegistryPos…

记录一个英语听力网站的开发

背景 在当前全球经济衰退的背景下&#xff0c;国内IT相关工作的竞争日益激烈。为了获得更多的职业机会&#xff0c;学习英语或许能为程序员打开一扇新的窗户。尤其是在国际化背景的远程工作中&#xff0c;英语协作沟通是必不可少的。 尽管我们大多数人从小到大都在学习英语&a…

使用Renesas R7FA8D1BH (Cortex®-M85)和微信小程序App数据传输

目录 概述 1 系统架构 1.1 系统结构 1.2 系统硬件框架结构 1.3 蓝牙模块介绍 2 微信小程序实现 2.1 UI介绍 2.2 代码实现 3 上位机功能实现 3.1 通信协议 3.2 系统测试 4 下位机功能实现 4.1 功能介绍 4.2 代码实现 4.3 源代码文件 5 测试 5.1 编译和下载代码…

RNN的反向传播

目录 1.RNN网络&#xff1a;通过时间反向传播(through time back propagate TTBP) 2.RNN梯度分析 2.1隐藏状态和输出 2.2正向传播&#xff1a; 2.3反向传播&#xff1a; 2.4问题瓶颈&#xff1a; 3.截断时间步分类&#xff1a; 4.截断策略比较 5.反向传播的细节 ​编辑…

大数据新视界 --大数据大厂之JavaScript在大数据前端展示中的精彩应用

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

浙大数据结构:05-树8 File Transfer

数据结构MOOC PTA习题 这道题考察并查集的操作&#xff0c;合并以及找根结点 机翻&#xff1a; 1、条件准备 node是数组存放1-N结点的根节点的&#xff0c;n为总结点数 #include <iostream> using namespace std;const int N 1e4 5; int node[N]; int n; 先初始化…

众数信科AI智能体政务服务解决方案——寻知智能笔录系统

政务服务解决方案 寻知智能笔录方案 融合民警口供录入与笔录生成需求 2分钟内生成笔录并提醒错漏 助办案人员二次询问 提升笔录质量和效率 寻知智能笔录系统 众数信科AI智能体 产品亮点 分析、理解行业知识和校验规则 AI实时提醒用户文书需注意部分 全文校验格式、内…

【在Linux世界中追寻伟大的One Piece】进程间关系与守护进程

目录 1 -> 进程组 1.1 -> 什么是进程组 1.2 -> 组长进程 2 -> 会话 2.1 -> 什么是会话 2.2 -> 如何创建会话 2.3 -> 会话ID(SID) 3 -> 控制终端 4 -> 作业控制 4.1 -> 什么是作业(job)和作业控制(Job Control) 4.2 -> 作业号 4.3…

Spring:项目中的统一异常处理和自定义异常

介绍异常的处理方式。在项目中&#xff0c;都会进行自定义异常&#xff0c;并且都是需要配合统一结果返回进行使用。 1.背景引入 &#xff08;1&#xff09;背景介绍 为什么要处理异常&#xff1f;如果不处理项目中的异常信息&#xff0c;前端访问我们后端就是显示访问失败的…

20240921在友善之臂的NanoPC-T6开发板上确认宸芯的数传模块CX6602N的AT命令

console:/dev # cat ttyUSB1 & console:/dev # echo AT > ttyUSB1 20240921在友善之臂的NanoPC-T6开发板上确认宸芯的数传模块CX6602N的AT命令 2024/9/21 21:03 【必须】Android12/Linux&#xff08;Buildroot&#xff09;都必须要&#xff01; 4、【Android12默认打开U…

电脑硬件-机械硬盘

简介 机械硬盘是电脑的主要存储媒介之一&#xff0c;通常用于存储一些文件资料或者学习视频笔记等比较大的内容。 结构 采用磁盘存储数据&#xff0c;使用温彻斯特的结构&#xff0c;特有四个特点&#xff1a; 1.磁头、盘片和运动机构安装在一个密封的腔体内。 2.盘片告诉旋…

一图快速看懂flink source的设计实现

文章目录 整体来说多个处理流程是解偶的&#xff0c;这样可以在面对多数据源情况下&#xff0c;能更加的灵活。 下面只展示了&#xff0c;主要的一些流程 下面补充一点&#xff0c;读取文件状态的保存&#xff0c;切分信息用了一个 ListState 来保存。具体要保存的信息&#x…

day2-1 app端文章查看

首先一共三张表 然后大致过程就是三层架构 用mp实现 具体出现的问题 1 测试的时候后端代码启动不了 先在maven clean一下 具体流程 然后执行完之后建议把这三个模块的target文件删除一下再运行 最后的话 如果还是报错 也是正常的 因为后边的东西都没写有些文件没有用到 2…

常见的中间件漏洞

Tomcat CVE-2017-12615 访问主页进行抓包 修改传参方式为put 放包进行连接 后台弱⼝令部署war包 访问主页试用默认账号密码tomcat/tomcat进行登录后 将哥斯拉生成的jsp木马文件压缩城成zip文件&#xff0c;然后再修改zip后缀文war 然后进行上传 使用哥斯拉进行测试连接 CVE-…

基于SpringBoot+Vue的在线酒店预订系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

微服务——网关登录校验(一)

1.网关登录校验 微服务中的网关登录校验是微服务架构中常见的一种安全机制&#xff0c;用于在请求到达微服务之前&#xff0c;对用户的身份进行验证&#xff0c;确保只有合法的用户才能访问相应的服务。 在微服务架构中&#xff0c;每个微服务都是独立部署的&#xff0c;它们之…

Apipost IDEA插件新升级,Apipost Helper上架IDEA插件市场

大家好&#xff01;今天向大家介绍一个非常方便的IDEA插件——Apipost Helper&#xff01;相信很多使用过Apipost的朋友在开发过程中都希望能够直接将编写好的API同步至Apipost&#xff0c;而无需手动填写。前段时间&#xff0c;Apipost推出了Apipost IDEA插件的内测版&#xf…

macOS平台编译libidn2库给iOS及macOS用

1.克隆源码: git clone https://gitlab.com/libidn/libidn2.git --recursive 2.安装依赖库: pkg-config也要安装 3.启动bootstrap生成configure 配置成功 configure生成成功

概率论与数理统计(2)

第一节博客已经整理了求导的公式&#xff0c;一些常用的概念。链接如下&#xff1a;高等数学基础&#xff08;1&#xff09;-CSDN博客。 第二节博客整理了微积分的公式及其相关概念。链接如下&#xff1a;高等数学基础&#xff08;2&#xff09;——微积分-CSDN博客 第三节博客…