写一个可以登录注册包括管理员身份、读者身份在内的,可以管理(增删改查)图书、借阅信息,可以借书还书的图书管理系统
使用数据库:SQL sever
使用语言:C#
使用IDE:Visual Studio
初步想法:
话不多说,第一步:建立数据库:
为此我们需要考虑关于建立哪些表的问题,首先我们肯定需要一个读者表和一个图书表,才外,我们还需要一个借阅信息表,来作为中介以便借书还书等活动,之后,还需要一个用户表,用来存放注册人信息。
//首先画出数据库的BR图///
说明:方框代表数据库的一个表,椭圆代表一个属性,菱形方框代表表之间的关系。
理论的数据库物理模型:
说明:"pk"为主键、“fk”为外键,表中的所有Bigint都应设置为自增模式
具体SQL语句:
use master--创建数据库Libraryif(exists(select * from master.dbo.sysdatabases where name = 'Library'))beginprint '已存在数据库Library,删除重建中。。。'drop database Libraryendgocreate database Librarygouse Librarygo--创建各个表create table LogInfo(tno bigint identity(1,1) primary key,--设置自增username char(20),passwd char(30),Logid char(6),check (Logid='admin' OR Logid='reader'))alter table LogInfo add constraint uniuserName unique(username)create table Books(ISBNum char(10) primary key,bname char(20) not null,bpress char(20),bwriter char(10),bnumAll int,bnumAvailable int,bifAvailable char(5),check(bnumAll>=0 AND bnumAvailable >=0))alter table Books addconstraint de_Books_Ifavailable default '可借' for bifAvailablecreate table Readers(rid char(20) primary key,rname char(20) not null,rsex char(2),rjob char(10),ravailable int,ralready int,rworkplace char(20),rtel char(11),check (rsex = '男'OR rsex ='女' ))alter table Readers addconstraint de_Readers_rsex default '男' for rsexcreate table BR(BRno bigint identity(1,1) primary key,ISBNum char(10),rid char(20),CheckOutDate date,DeadLine date,ReturnDate date,fine money,constraint FK_BR_BOOKS foreign key(ISBNum)references Books(ISBNum)on update cascadeon delete cascade,constraint FK_BR_READERS foreign key(rid)references Readers(rid)on update cascadeon delete cascade,check (fine>=0))alter table BR addconstraint de_BR_fine default 0 for fine
其中还加入了各种约束,请自行查看上面的代码
接下来为数据库添加角色,这一步可以方便之后的根据不同注册信息赋予不同权限的操作。
角色说明:
Lbry_admin:Library的管理员Lbry_reader:Library的读者
分别赋予以下权限:
grant all on Books to Lbry_admin with grant optiongrant all on BR to Lbry_admin with grant optiongrant all on LogInfo to Lbry_admin with grant optiongrant all on Readers to Lbry_admin with grant optiongrant select,update on Books to Lbry_readergrant select,update on Readers to Lbry_readergrant select,update,insert,delete on BR to Lbry_readergrant select,insert,update,delete on LogInfo to Lbry_reader
为了验证数据库创建是否成功,我设置了默认添加的用户和数据,默认添加的用户是:“tutu”和“ding”,默认的图书为:“tuBook”和“DingBook”,默认他们俩各借了一本书:
use masterif(exists(select * from master.dbo.syslogins where name = 'tutu'))beginexec sp_droplogin 'tutu'exec sp_dropuser 'tutu'endif(exists(select * from master.dbo.syslogins where name = 'ding'))beginexec sp_droplogin 'ding'exec sp_dropuser 'ding'endexec sp_addlogin 'tutu','123456','Library'exec sp_adduser 'tutu','tutu'EXEC master.dbo.sp_addsrvrolemember @loginame = N'tutu', @rolename = N'sysadmin'exec sp_addrolemember 'Lbry_admin','tutu'exec sp_addlogin 'ding','654321','Library'exec sp_adduser 'ding','ding'EXEC master.dbo.sp_addsrvrolemember @loginame = N'ding', @rolename = N'sysadmin'exec sp_addrolemember 'Lbry_admin','ding'print '数据库初始化完成,进行select * from LogInfo 查看初始化用户信息'use Libraryinsert into Books values ('1234567890','tubook','tupress','tutu',100,20,'是')insert into Books values ('0987654321','DIngbook','dingpress','ding',100,20,'是')insert into Readers values ('2292204175','tutu','男','学生',5,20,'学校','18120757777')insert into Readers values ('22925','ding','男','学生',5,20,'学校','13220721177')insert into BR(ISBNum,rid,CheckOutDate,DeadLine,ReturnDate,fine) values ('1234567890','2292204175','-01-01','-06-04','','0.00')insert into BR(ISBNum,rid,CheckOutDate,DeadLine,ReturnDate,fine) values ('0987654321','22925','-01-02','-06-05','','0.00')select * from Booksselect * from Readersselect * from BRinsert into LogInfo(username,passwd,Logid)values('tutu','123456','admin')insert into LogInfo(username,passwd,Logid)values('ding','654321','admin')select * from LogInfo
接下来,还需要完善数据库。如何完善?就是 给数据库添加方便我们使用的存储过程和函数程序:
这里我分别添加了如下内容:
OverDueInfo:逾期未还的图书和读者信息OverDueBooks:逾期未还的借阅信息ifAvailable:根据图书数量改变图书可借状态的触发器deleteReader:删除读者时同时删除相应用户信息的触发器
if exists(select * from sys.procedures where name='OverDueInfo') -- 逾期未还的图书和读者信息drop procedure dbo.OverDueInfogocreate procedure OverDueInfo@Rid char(20)asbeginbeginselect ISBNum as 'ISBN书号',bname as '书名',rname as '读者姓名' from Books,Readerswhere exists(select * from BR where DeadLine <= DATENAME(YEAR,GETDATE())+'/'+DATENAME(MONTH,GETDATE())+'/'+DATENAME(DAY,GETDATE()) and BR.ISBNum = Books.ISBNum and BR.rid = @Rid and Readers.rid = @Rid)endendif exists(select * from sys.procedures where name='OverDueBooks')-- 逾期未还的借阅信息drop procedure dbo.OverDueBooksgocreate procedure OverDueBooks@Rid char(20)asbeginbeginselect *from BRwhere DeadLine <= DATENAME(YEAR,GETDATE())+'/'+DATENAME(MONTH,GETDATE())+'/'+DATENAME(DAY,GETDATE()) and ReturnDate = '1900/1/1'and BR.rid = @Ridendendif(OBJECT_ID('ifAvilable') is not null) -- 关于图书是否可借的触发器drop trigger ifAvilable gocreate trigger ifAvilableon Books for update asdeclare @numAvailable int = 1declare @ISBNum char(10)select @numAvailable = bnumAvailable,@ISBNum = ISBNum from inserted if(@numAvailable > 0)update Books set bifAvailable = '是' where ISBNum = @ISBNumelseupdate Books set bifAvailable = '否' where ISBNum = @ISBNumgoif(OBJECT_ID('deleteReader') is not null) -- 删除读者信息时也删除相关用户信息的触发器 drop trigger deleteReader gocreate trigger deleteReaderon Readers for delete asdeclare @Rname char(20)select @Rname = rname from deleted delete from LogInfo where username = @Rname
第二步:编写窗体程序
由于本部分代码太多,只展示效果,源码在文末下载查看
在visual studio中建立新的Windows窗体程序:
如果没有请在工具栏中下载这个工具:
我写的程序的总类表:
接下来使用C#自带的工具绘制出类似下图的结构,并对每一个组件命名,记住这些名字,方便自己之后调用。
用户登录/注册模块
功能
进行用户的登录、注册。
模块流程
输入正确的账户密码登录或者进行注册,对于管理员的注册,还可以进行管理员的身份验证。默认的校验码是123456 。
当用户选择不同的身份时,会自动跳出不同的信息填写界面,如果是管理员会跳出校验码填写界面。如果是读者,会跳出详细的读者信息填写。
输入输出项
输入:用户的账户密码
输出:用户的身份以及权限,根据这个进行界面切换。
重点类描述
Signin:进行注册校验,同时需要向数据库新增这样的用户以及赋予其相关的权限。
重点算法
这里要注册就要先登录数据库,默认的初始登录账户已经在sql文件中创建,为“tutu;123456”
其中,赋予权限的部分比较重要,使用的SQL语句是:
signinTran = String.Format(@"set xact_abort on exec sp_addlogin '{0}', '{1}','Library' exec sp_adduser '{2}','{3}' exec sp_addrolemember '{4}','{5}' insert into LogInfo(username,passwd,Logid) values('{6}','{7}','{8}') ",username,password,username,username,role,username,username,password,id_box.Text );
限制条件
管理员需要输入校验码。
7.2. 读者信息管理模块
功能
实现读者信息的管理,包括修改新增删除操作。
其中新增键参考的数据是上面这一排所输入的数据。
在没有选择数据的时候,或者DataGridBox中没有数据的时候,删除键和修改键是无效的,可以进行新增信息。点击修改,会弹出新的窗体专门进行修改。
其中:
刷新:刷新当前查询的结果,一般由于程序不是循环刷新的,所以显示出来的信息可能会存在一些错误或者缺失,点击刷新可以查看最新的信息
复位:将上面这些文本框中的数据恢复成默认数据。
查看该读者未还书籍信息:查看当前选择的读者有哪些未还信息。
模块流程
输入:根据文本框的数据形成的SQL语句
输出:查询或者修改的结果,操作都会有提示。
重点算法
关于如何实现查看未还书籍信息:
数据库内已经编写了一个程序procedure 即之前说的OverDueBooks
只需要在程序内进行调用即可。
7.3. 图书信息管理模块
功能
总体功能与读者管理模块类似
7.4. 借阅信息管理模块
总体功能的使用与之前的图书管理和读者管理类似。
注意其中的日期相关选择框中是一个日期组件,可以图形化选择日期,不用手动输入。
修改时,是否逾期结果自动生成,并根据超时日期计算罚款金额
7.5. 读者查询图书信息模块
功能
实现读者对于所有书籍信息的查询和借阅。
在点击借阅之后,读者的可借数量会自动减一,读者的已借数量会自动加一。该图书的可借数量会自动减一。
而图书是否可借的信息,有数据库内的trigger进行约束,若可借数量小于1则自动更改可借状态为否。
模块流程
点击查询,找到要借的书籍,点击借书即可。
输入输出项
输入:查询语句、借书请求
输出:查询结果、借书结果
限制条件
只能给自己借书
7.6. 读者查看读者信息模块
功能
可以查询所有读者信息,并且可以修改自己的信息,但是仅限于修改工作职称、性别、工作地点、电话,其他的信息可以显示但是不可以修改。
模块流程
点击查询,显示读者信息仅可供查看,点击修改我信息可以进入修改本人信息界面。
输入输出项
输入:SQL查询语句
输出:查询结果,是否修改自己的信息成功
限制条件
只能修改自己的信息。
7.7. 读者查阅借阅信息模块
功能
查询自己所有的借阅信息
查询自己已经到期的图书
还书
模块流程
点击查询,可以查看自己已借的所有书籍记录
点击到期图书,可以查看自己到期的图书。
点击还书可以进行还书,会自动根据还书日期进行罚款和个人书本数量增减、总图数增减。
重点算法
关于查询到期图书的SQL语句:
string OverDueSQL = String.Format(@"select * from BR where DeadLine <= DATENAME(YEAR,GETDATE())+'/'+DATENAME(MONTH,GETDATE())+'/'+DATENAME(DAY,GETDATE()) and ReturnDate = '1900/1/1' and BR.rid ='{0}'", publicVar.currentRid.Trim());
限制条件
只能操作自己的信息。
使用手册
确认自己打开了本地的SQL服务:
2. 在本地数据库运行初始化数据库的SQL文件(源码文件中有)
最后应该可以在结果中看到初始化的数据库表,说明初始化成功。
3. 注册管理员时,你需要输入正确的管理员校验码,否则无效(默认为123456):
4. 注册读者时,必须要填写读书卡号和性别,否则不成功:
5. 注册的读书卡号不能与其他人重复:
6. 管理员进行插入数据时,不可以插入主键为空的数据:
7. 读者点击到期图书可以查看自己到期以及即将到期的的图书,点击还书可以查看自己还书的结果(超时一天罚款0.2元):
8. 不能归还已经归还的书籍:
9. 点击缴纳罚款即可缴纳所有罚款,点击到期图书可以查看自己已经到期的图书信息:
10. 罚款的金额是每超一天罚款0.2元
11. 读者借书时,如果书本可借数量为0 ,则会提示:
12. 说明:所有的日期变量默认设置为1900-01-01.
13. 所有的修改操作都会提示修改的内容。
14. 本数据库初始的表数据:
源码下载:
说明:本代码仅供交流使用,请勿用作自己的实验代码,否则因为抄袭本代码而导致的一切后果,概不负责。
源码下载点击此处