【数据库——MySQL(实战项目1)】(4)图书借阅系统——触发器

news2024/11/26 6:24:35

目录

  • 1. 简述
  • 2. 功能代码
    • 2.1 创建两个触发器,分别在借出或归还图书时,修改借阅人表中的已借数目(附加:借阅人表的总借书数、图书表的借阅次数以及更新图书表的图书状态为(已借出/在架上))字段;
    • 2.2 创建触发器,当借阅者已借阅的书籍数目达到限额(附加:当借阅者证件号不存在、借阅者星级为 `0`、重复借入同一本书籍【未还同一本书的情况下】、图书已经被他人借了(此情况只发生在线上预约的时候-目前构建的数据库只适用于线下)、书籍不存在时)时,禁止借入新的书籍;
    • 2.3 创建触发器,当要从借阅人表中删除借阅人时(毕业了),需要先判断此借阅人是否有书未还,有的话禁止从借阅人表中删除此借阅人。
  • 结尾

1. 简述

在介绍本项目功能前,突然有感而发,讲讲我是如何对待程序员不写注释的吧(不感兴趣的小伙伴可以跳过这段话~)。作为一名合格的程序员,写注释是最基本的要求!!!它有如下好处:

  1. 帮助你回忆起这段代码在干什么?大家都写过代码吧,代码长度或长或短。可能一些短代码在仔细阅读后可以知道它在干什么,但是阅读代码的时间我相信我已经看了几个短代码的注释了!所以写注释可以提高我们读代码的效率(这是基于短代码而言的)。对于长代码,比如我写过的背单词软件(森林背词),仅仅是完成基础的背词、复习、调整各单词复习时间、利用数据库存储数据(不包含一些活动、优惠券之类)的代码就有 1w+ 的代码行数了(python 代码,如果是其它的代码可能更长~),如果不写注释,加上过了一段时间之后,连我自己都不记得某一段代码是干什么的了。。。但是有注释就不一样了,想要了解或者修改某一个功能代码时,只要搜索以下注释的关键字就能马上定位(这个也是血的教训!!!)。在重构森林背词之前,我用 python 写过一次,那时候写的功能更简单,但是要想从旧版本升级到新版本(重构),就要对原代码有一定的了解,因为之前没写过注释,所以看每个功能都很慢,最后干脆从头重写代码,这也导致我的工作量激增~
  2. 写注释除了帮助你自己了解和修改代码外,也可以帮助别人了解和修改你的代码。你也不想接手一个旧项目的代码,发现里面啥注释也没有吧,这样当你要维护的时候,时间成本是很大的
  3. 当然注释的质量也是很重要的,要是一段注释说了跟没说一样,或者说的牛头不对马尾,那只会浪费你的时间。
  4. 除了注释,还有一个重点就是功能一定要分模块来写,不要全写在一个文件里面,要不然要你修改的时候你会崩溃。这里还有一个好处就是可以多人协作编写不同的功能代码~

那么下面就正式开始图书借阅系统的最后一篇介绍文章~


这篇文章将主要完成图书借阅系统的 9~11 题(触发器),即:

  1. 创建两个触发器,分别在借出或归还图书时,修改借阅人表中的已借数目(附加:借阅人表的总借书数、图书表的借阅次数以及更新图书表的图书状态为(已借出/在架上))字段;
  2. 创建触发器,当借阅者已借阅的书籍数目达到限额(附加:当借阅者证件号不存在、借阅者星级为 0、重复借入同一本书籍【未还同一本书的情况下】、图书已经被他人借了(此情况只发生在线上预约的时候-目前构建的数据库只适用于线下)、书籍不存在时)时,禁止借入新的书籍;
  3. 创建触发器,当要从借阅人表中删除借阅人时(毕业了),需要先判断此借阅人是否有书未还,有的话禁止从借阅人表中删除此借阅人。

:临时多了一些想法,把第 10 题新增了一些功能~

2. 功能代码

2.1 创建两个触发器,分别在借出或归还图书时,修改借阅人表中的已借数目(附加:借阅人表的总借书数、图书表的借阅次数以及更新图书表的图书状态为(已借出/在架上))字段;

# 借书触发器
drop TRIGGER if exists tri_update_borrowerlend;
delimiter $
create TRIGGER tri_update_borrowerlend after insert on information for each row
begin
	update borrower
		set borrowedCount = borrowedCount + 1
		where id = new.borrowerid;
	update borrower
		set borrowedAll = borrowedAll + 1
		where id = new.borrowerid;
	update book
		set lendCount = lendCount + 1
		where id = new.bookid;
	update book
		set state = '已借出'
		where id = new.bookid;
end$
delimiter ;
# 还书触发器
drop TRIGGER if exists tri_update_borrowerreturn;
delimiter $
create TRIGGER tri_update_borrowerreturn after update on information for each row
begin
	update borrower
		set borrowedCount = borrowedCount - 1
		where id = new.borrowerid;
	update book
		set state = '在架上'
		where id = new.bookid;
end$
delimiter ;

检测触发器是否正确:

# (触发器1)在借出图书时,修改借阅人表中的已借数目(附加:借阅人表的总借书数、图书表的借阅次数以及更新图书表的图书状态为(已借出/在架上))字段;
select * from borrower;
select book.id as 图书编号, book.lendCount as 借阅次数, book.state as 图书状态 from book;
call p_InsertLeadInfo(2020312011047,101101699412);
select * from borrower;
select book.id as 图书编号, book.lendCount as 借阅次数, book.state as 图书状态 from book;

# (触发器2)在归还图书时,修改借阅人表中的已借数目字段;
call p_UpdateLeadInfo(2020312011047,101101699412);
select * from borrower;
select book.id as 图书编号, book.lendCount as 借阅次数, book.state as 图书状态 from book;

测试结果如下:

  1. 触发器1(借书触发器)

    在这里插入图片描述

    可见此触发器是生效的,能够在借出图书时,将借阅人表中的当前借阅数目 +1,借阅人表的总借书数 +1、图书表的借阅次数 +1 以及图书表的图书状态从“在架上”更新为“已借出”。

  2. 触发器2(还书触发器)

    在这里插入图片描述
    可见此触发器是生效的,能够在归还图书时,将借阅人表中的当前借阅数目 -1 以及图书表的图书状态从“已借出”更新为“在架上”。

2.2 创建触发器,当借阅者已借阅的书籍数目达到限额(附加:当借阅者证件号不存在、借阅者星级为 0、重复借入同一本书籍【未还同一本书的情况下】、图书已经被他人借了(此情况只发生在线上预约的时候-目前构建的数据库只适用于线下)、书籍不存在时)时,禁止借入新的书籍;

drop trigger if EXISTS tri_insertinfo;
delimiter $
create TRIGGER tri_insertinfo before insert on information for each row
begin
	# 借阅者已借阅的书籍数目达到限额可使用存储函数f_ReBorrowTimes()完成
	declare a int;
	declare b int;
	declare repeat_borrow int;		# 是否重复借入书籍
	declare c int;		# 0:图书已借出:1:图书在架上
	declare d int;

	select count(*) into a
	from borrower
	where borrower.id = new.borrowerid;
	
	select count(*) into b
	from borrower
	where borrower.grade = 0 and borrower.id = new.borrowerid;
	
	SELECT if(returnDateReality is null, 0, 1) INTO repeat_borrow
	FROM information
	WHERE information.borrowerid = new.borrowerid AND information.bookid = new.bookid
	ORDER BY returnDateReality ASC
	LIMIT 1;
	
	select if(book.state='已借出',0,1) into c
	from book
	where book.id = new.bookid;
	
	select count(*) into d
	from book
	where book.id = new.bookid;
	
	if a = 0 then 
		SIGNAL SQLSTATE '12345' 
		set message_text = '证件号不存在';
	elseif b != 0 then 
		SIGNAL SQLSTATE '12346' 
		set message_text = '借阅人等级为0(已列为失信人,禁止借入书籍)';
	elseif f_ReBorrowTimes(new.borrowerid) <= 0 then 
		SIGNAL SQLSTATE '12347' 
		set message_text = '已借阅的书籍数目达到限额';
	elseif repeat_borrow = 0 then 
		SIGNAL SQLSTATE '12348' 
		set message_text = '书籍禁止重复借入';
	elseif c = 0 then 
		SIGNAL SQLSTATE '12349' 
		set message_text = '图书已被他人借阅';
	elseif d = 0 then 
		SIGNAL SQLSTATE '12350' 
		set message_text = '图书不存在';
	end if;
	
end$
delimiter ;

检测触发器是否正确:

# 借阅者已借阅的书籍数目达到限额
call p_InsertLeadInfo(2020312011047,101102308670);
call p_InsertLeadInfo(2020312011047,101102698766);
call p_InsertLeadInfo(2020312011047,451100004441);
# 借阅者证件号不存在
call p_InsertLeadInfo(9999999999999,101101699410);
# 借阅者星级为0
update borrower set grade = 0 where id = 2018210210205;
call p_InsertLeadInfo(2018210210205,101101699410);
# 重复借入同一本书籍【未还同一本书的情况下】
call p_InsertLeadInfo(1000000000001,101101699410);
call p_InsertLeadInfo(1000000000001,101101699410);
# 图书已经被他人借了
call p_InsertLeadInfo(1000000000002,101101699410);
# 书籍不存在
call p_InsertLeadInfo(1000000000002,999999999999);

测试结果如下:

  1. 已借阅书籍达到限额(学生)【教师借阅是超过 10 本书就会触发此触发器,这里不进行演示,感兴趣的读者可自行验证~】:

    在这里插入图片描述
    从上面 触发器2(还书触发器) 的借阅人表可知证件号为“ 2020312011047 ”的借阅人(学生)已经借了 3 本书了,所以再借 2 本后,当继续借多 1 本时,显示借阅书籍数目达到上限,无法继续借阅。

  2. 证件号不存在:

    在这里插入图片描述
    证件号 9999999999999 不存在时,无法借阅书籍。

  3. 借阅人星级为 0 (已列为失信人,禁止借入书籍):

    在这里插入图片描述
    失信人(即长期逾期不还图书的用户)无法借阅书籍。

    :此系统没有写降低用户星级的代码(例如长期逾期不还图书的用户根据次数或者时长降低用户星级),同样可以按照用户恢复正常使用后多少天就增加用户星级(增加的星级不能超过 5 颗星,默认用户最多只有 5 颗星),读者可以自行编写~

  4. 书籍禁止重复借入:

    在这里插入图片描述
    书籍在第一次成功借出,在第二次借出失败。即书籍禁止重复借入(未还的情况下再次借入,即借入行为重复操作)。

  5. 图书已被他人借阅:

    在这里插入图片描述
    这本书刚刚已经借出了(在测试 4. 书籍禁止重复借入 时借出了),因此他人不可再借阅,其实在实际当中,这种情况基本上不会发生(除非用户本人一直借这本书 或者 这本书遗失被其他人借阅)。

  6. 图书不存在:

    在这里插入图片描述
    当输入的图书编号(如这里的 999999999999)不存在时,无法借入,其实这种情况也不会发生,除非是借阅时工作人员输入错误 或者 机器识别错误

2.3 创建触发器,当要从借阅人表中删除借阅人时(毕业了),需要先判断此借阅人是否有书未还,有的话禁止从借阅人表中删除此借阅人。

drop trigger if EXISTS tri_delete_borrower;
delimiter $
create TRIGGER tri_delete_borrower before delete on borrower for each row
begin
	declare a int DEFAULT 0;

	select count(*) into a
	from book join information on book.id = information.bookid
						join borrower on borrower.id = information.borrowerid
	where borrower.id = old.id and information.returnDateReality is null;

	if a != 0 then 
		SIGNAL SQLSTATE '12351' 
		set message_text = '借阅人还有书籍未还,无法删除此借阅人';
	end if;
	
	# 如若数据库储存量过大,不想保存非在校师生数据,可以保留下述删除语句
	delete from information where information.borrowerid = old.id;
	
end$
delimiter ;

检测触发器是否正确:

# 借阅人有书籍未还,无法删除
delete from borrower where id = 2020312011047;
# 借阅人无书籍未还,可以删除
select * from borrower;
delete from borrower where id = 2021312011002;
select * from borrower;

测试结果如下:

  1. 借阅人有书籍未还,无法删除:

    在这里插入图片描述

  2. 借阅人没有书籍未还,可以删除:

    在这里插入图片描述

结尾

好啦,本次的 MySQL 实战项目1 的介绍就到此结束了,后续如若有其它好的实战项目,我会继续分享~

大家感觉有帮助的可以点赞、收藏 + 关注哦,你的支持是我持续分享的动力~

上一篇文章:【数据库——MySQL(实战项目1)】(3)图书借阅系统——存储函数

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

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

相关文章

测试老鸟,Jmeter两种方法造接口性能测试数据(超细整理)

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

mysql面试题51:你是如何监控你们的数据库的?你们的慢日志都是怎么查询的?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:你是如何监控你们的数据库的? 监控数据库是确保数据库系统稳定性和性能的重要工作。下面是一些常见的方法和工具: 监控工具选择:选择适合你的数…

排序:为什么插入排序比冒泡排序更受欢迎?

文章来源于极客时间前google工程师−王争专栏。 需掌握的的排序&#xff1a;冒泡排序、插入排序、选择排序、归并排序、快速排序、计数排序、基数排序、桶排序。按照时间复杂度可以分为三类&#xff1a; 问题&#xff1a;插入排序和冒泡排序的时间复杂度相同&#xff0c;都是O(…

UML组件图综合指南:设计清晰、可维护的软件系统

介绍&#xff1a; UML&#xff08;Unified Modeling Language&#xff09;组件图是软件系统设计中的重要工具&#xff0c;用于描绘系统的物理结构和组件之间的关系。在软件工程中&#xff0c;通过创建清晰的组件图&#xff0c;团队能够更好地理解系统的模块化结构和组织关系&a…

PTE考试解析

Pte 考试题目 注入漏洞 空格被过滤 用/**/代替空格&#xff0c;发现#被过滤 对&#xff03;进行url编码为%23 输入构造好的payload http://172.16.12.100:81/vulnerabilities/fu1.php?id1%27)/**/and/**/11%23 http://172.16.12.100:81/vulnerabilities/fu1.php?id1%27)/*…

uniapp 一次性上传多条视频 u-upload accept=“video“ uni.chooseMedia uni.uploadFile

方式 一 部分安卓机 只能一条一条传视频 文档地址 uview 2.0 Upload 上传组件 html <view class"formupload"><u-upload accept"video":fileList"fileList3" afterRead"afterRead" delete"deletePic" name"…

解锁远程联机模式:使用MCSM面板搭建我的世界服务器,并实现内网穿透公网访问

文章目录 前言1.Mcsmanager安装2.创建Minecraft服务器3.本地测试联机4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射内网端口 5.远程联机测试6. 配置固定远程联机端口地址6.1 保留一个固定TCP地址6.2 配置固定TCP地址 7. 使用固定公网地址远程联机 前言 MCSManager是一个…

动态资源平衡:主流虚拟化 DRS 机制分析与 SmartX 超融合的实现优化

资源的动态调度是虚拟化软件&#xff08;或超融合软件&#xff09;中的一项重要功能&#xff0c;主要指在虚拟化集群中&#xff0c;通过动态改变虚拟机的分布&#xff0c;达到优化集群可用性的目标。这一功能以 VMware vSphere 发布的 Distributed Resource Scheduler&#xff…

atoi函数及其模拟实现

这个函数的功能是将字符串转换为整形&#xff0c;那么具体是怎么样的呢 先看几个例子&#xff1a; 有一个转换为整形的最大值 刚开始就是非法字符 因此&#xff0c;我们模拟实现时&#xff0c;要考虑以上几种非法输入情况&#xff1a; 1.空字符串 2.空白字符 3.处理-号 4.过大…

C++算法:城市天际线问题

题目 城市的 天际线 是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度&#xff0c;请返回 由这些建筑物形成的 天际线 。 每个建筑物的几何信息由数组 buildings 表示&#xff0c;其中三元组 buildings[i] [lefti, righti, heighti] 表示&am…

【无标题】SpringMVC之WEB-INF下页面跳转@ModelAttributeIDEA tomcat控制台中文乱码问题处理

WEB-INF下页面跳转 ModelAttribute来注解非请求处理方法 用途&#xff1a;预加载数据&#xff0c;会在每个RequestMapping方法执行之前调用。 特点&#xff1a;无需返回视图&#xff0c;返回类型void IDEA tomcat控制台中文乱码问题处理 复制此段代码&#xff1a;-Dfile.e…

快速生成美观的二维码:专家级教程

首先&#xff0c;我们需要选择一个适合在线海报制作工具&#xff0c;比如乔拓云。乔拓云是一个非常流行的在线海报制作工具&#xff0c;它提供了大量的模板和编辑工具&#xff0c;让你可以轻松地制作出一张精美的Logo。 接下来&#xff0c;我们需要在乔拓云网站上注册并登录。在…

【运维笔记】VMWare 另一个程序已锁定文件的一部分,进程无法访问

情景再现 这里使用的是VMware 17 解决办法 进入设置 点击选项&#xff0c;全选复制里面内容 进入文件夹&#xff0c;删除所有包含.lck后缀的文件和文件夹 再启动虚拟机即可

关键词搜索快手商品列表数据,快手商品列表数据接口,快手API接口

在网页抓取方面&#xff0c;可以使用 Python、Java 等编程语言编写程序&#xff0c;通过模拟 HTTP 请求&#xff0c;获取快手网站上的商品页面。在数据提取方面&#xff0c;可以使用正则表达式、XPath 等方式从 HTML 代码中提取出有用的信息。值得注意的是&#xff0c;快手网站…

多目标水母搜索算法(Multi-Objective Jellyfish Search algorithm,MOJS)求解微电网优化--提供MATLAB代码

一、微网系统运行优化模型 微电网优化模型介绍&#xff1a; 微电网多目标优化调度模型简介_IT猿手的博客-CSDN博客 参考文献&#xff1a; [1]李兴莘,张靖,何宇,等.基于改进粒子群算法的微电网多目标优化调度[J].电力科学与工程, 2021, 37(3):7 二、多目标水母搜索算法MOJS …

@Mapper与@MapperScan注解

Mapper Mapper Mapper.xml文件 作用在dao&#xff08;mapper&#xff09;层上的一个注解&#xff0c;将接口生成一个动态代理类&#xff0c;有了这个注解就不用 再写Mapper.xml文件 如果缺少这个注解&#xff0c;运行项目就会报相应的错误 Field userMapper in com.example…

docker入门加实战—docker数据卷

docker入门加实战—docker数据卷 容器是隔离环境&#xff0c;容器内程序的文件、配置等都在容器的内部&#xff0c;要读写容器内的文件非常不方便。 因此&#xff0c;容器提供程序的运行环境&#xff0c;但是程序运行产生的数据、程序运行依赖的配置都应该与容器进行解耦。 …

dpdk/spdk/网络协议栈/存储/网关开发/网络安全/虚拟化/ 0vS/TRex/dpvs技术专家成长体系教程

课程围绕安全&#xff0c;网络&#xff0c;存储&#xff0c;云原生4个维度去讲解核心技术点。 6个专栏组成&#xff1a;dpdk网络专栏、存储技术专栏、安全与网关开发专栏、虚拟化与云原生专栏、测试工具专栏、性能测试专栏 一、dpdk网络 dpdk基础知识 多队列网卡&#xff0…

es6(三)—— set(集合) 和map的使用

ES6的系列文章目录 第一章 Python 机器学习入门之pandas的使用 文章目录 ES6的系列文章目录一、set&#xff08;集合&#xff09;0. 定义1. 基本使用2.常用方法&#xff08;1&#xff09;代码&#xff08;2&#xff09;效果&#xff08;3&#xff09;遍历 二、map0. 定义1. 基…

利用Python分析金融交易中的滚动Z值

大家好&#xff0c;在不断演变的证券交易领域&#xff0c;能够利用数据和统计学的力量提供重要的优势。无论是预测未来价格、分析市场趋势&#xff0c;还是简单地评估特定证券的波动性&#xff0c;数据驱动的见解已经改变了交易者对证券市场的处理方式。这就是Z值的用途&#x…