十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
目录
创新互联是一家专注于成都网站制作、成都做网站与策划设计,拱墅网站建设哪家好?创新互联做网站,专注于网站建设十余年,网设计领域的专业建站公司;建站业务涵盖:拱墅等地区。拱墅做网站价格咨询:18980820575
目录 2
1 前言 4
1.1 目的 4
1.2 范围 4
1.3 有关本系统中的定义 4
2 资料引用 4
3 设计思路 4
3.1 数据层设计 5
user_book表的触发器 5
用户续借图书的存储过程 6
到期催还表的视图 7
3.2 数据链接层设计 8
UserBook Entity Bean设计 9
UserConsumer Entity Bean设计 10
UserLogBook Entity Bean设计 11
3.3 数据逻辑层设计 12
TheBook Session Bean设计 13
TheUser Session Bean设计 14
TheLog Session Bean设计 15
3.4 网络应用层设计 15
CheckValue bean 16
EnCode bean 16
JDBCBean bean 16
Rank bean 16
SetUp bean 16
SplitPage bean 17
UserLogin bean 17
SearchBook bean 17
SearchDeadline bean 17
ValidateIMG servlet 17
GetDelete servlet servlet 17
GetBookSubmit servlet 18
GetUserSubmit servlet 18
GetRenewBook servlet 18
GetBorrowBook servlet 18
GetReturnBook servlet 18
4 程序架构 18
4.1 程序组织结构 18
4.2 功能权限划分 20
4.3 WEB程序/页面设计 21
4.4 本系统实现的功能 22
5 任务分工 22
1 前言
1.1 目的
本文档详细描述了图书管理系统的设计,主要是为开发人员提供,使其对本项目的构建和维护有深入的了解。
1.2 范围
本文档的描述只针对图书管理系统的1.0版本。
1.3 有关本系统中的定义
以下是本说明书中用到的专门术语的定义和外文首字母组词的原词组:
术语或缩写 定义与描述
booksManager 本系统的名称
Reader 系统权限:普通读者
BookAdmin 系统权限:图书管理员
UserAdmin 系统权限:用户管理员
SuperAdmin 系统权限:超级管理员(系统管理员)
Undergraduate 系统用户角色:本科生
Graduate 系统用户角色:研究生
Teacher 系统用户角色:教师
2 资料引用
清华大学《应用软件平台与核心技术》讲义 顾明
清华大学《应用软件平台与核心技术》助教文档 张伟业、魏岚、陈勇、林彩荣
《精通EJB(第二版)》
《J2EE应用与BEA Web Logic Server》,刑国庆等译,电子工业出版社 2002.4
《设计模式——可复用面向对象软件的基础》,Erich Gamma等,机械工业出版社
3 设计思路
本系统严格按照4层结构设计,分为数据层(SQL server),数据链接层(entity bean),数据逻辑层(session bean),网络应用层(java bean, java servlet, java serverpage)。
四层之间完全独立,可以部署在四台服务器上运行,体现了分布式应用的思想。
数据层的功能严格来说是实现基本的数据存储(逻辑处理功能应该全部交给CMP管理),但因为学习原因,在数据库中也用到了一些逻辑处理,如使用了存储过程+系统级临时表处理读者续借图书的功能、使用触发器防止未还书的用户和未归还的图书被注销以及使用视图检测借书记录实现到期催还功能。
数据链接层实现了和数据库的连接,作用在于屏蔽数据库和平台之间的差异,做到底层无关性。本层利用了模糊查找、多表映射、Relationship等技术,通过find,select方法数据的查找功能,抛出聚集对象或远程接口对象给下一层。
数据逻辑层实现了对数据的逻辑处理,例如将远程接口对象转化为值对象、将聚集对象转化为值对象向量、利用日期类完成查找两个特定日期之间的记录等相对复杂的计算。
网络应用层完成页面跳转和页面显示等应用功能,还有一些附加功能如:图片验证,登录验证,等级控制,代码过滤,分页控制,输入值检测、借书日志打印、系统运行日志记录以及系统设置等。(使用了JDBC实现存储过程和模糊查找图书的功能)
3.1 数据层设计
数据库表
表名 功能描述
user_consumer 记录了用户的所有信息
user_book 记录了图书的所有信息
user_logBook 记录了用户使用本系统的信息,保留了所有的借书记录,可作为系统日志和报表资料
user_book表的触发器
用到的触发器之一,作用:如果要注销的图书被外借没有归还,则回滚此删除操作。
CREATE TRIGGER bookhavelog ON dbo.user_book
FOR DELETE
AS
declare @bookISBN varchar(50)
select @bookISBN=book_ISBN from deleted
if exists(select * from user_logBook where logb_book_ISBN=@bookISBN and
logb_backdate is null)
begin
rollback
return
end
用户续借图书的存储过程
利用存储过程实现用户续借图书的逻辑操作,根据用户的当前信息判断其是否有续借的权限,并把处理结果输出到临时表中去。
CREATE PROCEDURE user_renew_book @xxxparm int AS
CREATE TABLE ##temp(statement varchar(50))
DECLARE @username varchar(50)
SET @username=(select logb_cons_username from user_logBook where ID=@xxxparm)
IF @username is null
BEGIN
INSERT INTO ##temp VALUES ('The ID is not EXIST')
RETURN
END
DECLARE @timelimit int
SET @timelimit=(select logb_timelimit from user_logBook where ID=@xxxparm)
DECLARE @renewday int
SET @renewday=(select cons_maxday from user_consumer where cons_username=@username)
DECLARE @maxrenew int
SET @maxrenew=(select cons_maxrenew from user_consumer where cons_username=@username)
IF (@renewday*@maxrenew)=@timelimit
BEGIN
update user_logBook set logb_timelimit=logb_timelimit+@renewday where ID=@xxxparm
--update user_consumer set cons_maxrenews=cons_maxrenews-1 where cons_username=@username
INSERT INTO ##temp VALUES ('renew successful')
RETURN
END
ELSE
BEGIN
INSERT INTO ##temp VALUES ('You are not allowed to renew the book')
RETURN
END
GO
到期催还表的视图
利用DATEDIFF,DATEADD,CAST,GETDATE等函数从借书记录表中计算出到期的记录,然后根据此记录找出相应的读者信息,在网页上以email形式催还。
CREATE VIEW dbo.deadline
AS
SELECT TOP 100 PERCENT dbo.user_logBook.logb_cons_username,
dbo.user_logBook.logb_outdate, DATEADD([day], dbo.user_logBook.logb_timelimit,
CAST(dbo.user_logBook.logb_outdate AS datetime)) AS deadline_date, GETDATE()
AS now_date, dbo.user_consumer.cons_name, dbo.user_consumer.cons_kind,
dbo.user_consumer.cons_rank, dbo.user_consumer.cons_email,
dbo.user_consumer.cons_maxrenew, dbo.user_consumer.cons_maxbook,
dbo.user_logBook.logb_book_ISBN, dbo.user_book.book_name,
dbo.user_book.book_kind, dbo.user_book.book_storage, dbo.user_book.book_rank,
dbo.user_logBook.logb_timelimit
FROM dbo.user_logBook INNER JOIN
dbo.user_consumer ON
dbo.user_logBook.logb_cons_username = dbo.user_consumer.cons_username INNER
JOIN
dbo.user_book ON
dbo.user_logBook.logb_book_ISBN = dbo.user_book.book_ISBN
WHERE (DATEDIFF([day], DATEADD([day], dbo.user_logBook.logb_timelimit,
CAST(dbo.user_logBook.logb_outdate AS datetime)), GETDATE()) = 0) AND
(dbo.user_logBook.logb_backdate IS NULL)
ORDER BY dbo.user_logBook.logb_cons_username DESC
3.2 数据链接层设计
entity bean
UserBook Entity Bean设计
userbook remotehome接口
方法 描述
findAllBook 得到所有的图书信息
findByISBN 通过图书的书号得到图书的信息
findSearcher 利用关键字模糊查找图书信息
selectUserByBookISBN
(userbook remote) 利用select方法实现多表相关的查找
findSearcher实现模糊查找的代码:
select object(p) from UserBook as p where p.bookName like concat(concat('%',?1),'%') or p.bookAuthor like ?1 or p.bookKind like ?1 or p.bookPublish like ?1 or p.bookAbstract like ?1 or p.bookISBN like concat(concat('%',?1),'%') or p.bookRemark like ?1
UserConsumer Entity Bean设计
UserConsumer remotehome接口
方法 描述
findAllUser 查找所有的用户信息
findByUsername 通过用户名查找用户信息
findSearcher 利用关键字模糊查找用户信息
selectBookByUsername
(userconsumer remote) 利用select方法实现多表相关的查找
findSearcher实现模糊查找的代码:
select object(p) from UserConsumer as p where p.consUsername like concat(concat('%',?1),'%') or p.consSerial like ?1 or p.consName like concat(concat('%',?1),'%') or p.consRemark like ?1 or p.consEmail like ?1
UserLogBook Entity Bean设计
UserLogBook remotehome接口
方法 描述
findallbybookISBN 查找此书所有的借阅记录
findbybookISBN 查找此书当前的借出记录
findallbyusername 查找此用户所有的借阅记录
findbyusername 查找此用户当前的借出书记录
findbacklog 得到所有已经归还图书的借书记录
findoutlog 得到所有尚未归还图书的借书记录
findbyID 通过记录流水号查找借书记录
findlogbyday 查找某一日期的借书记录
(模糊匹配,例如提交“2004-5”可得到最终记录时间——借阅或归还在2004年5月份的所有借书记录)
findallog 得到所有的借书记录
FindLogByDay通过模糊匹配得到一组最终记录时间的代码:
select object(p) from UserLogBook as p where ( p.logbBackdate is null and p.logbOutdate like concat(concat('%',?1),'%') ) or ( p.logbBackdate is not null and p.logbBackdate like concat(concat('%',?1),'%') )
3.3 数据逻辑层设计
session bean
TheBook Session Bean设计
TheBook bean
实现图书的增删改查以及模糊搜索、通过书查读者等功能
方法内部实现所有的逻辑处理和转化,返回到远程接口值对象或值对象向量
TheUser Session Bean设计
TheUser bean
实现用户(读者)的增删改查以及模糊搜索、通过读者查书等功能
方法内部实现所有的逻辑处理和转化,返回到远程接口值对象或值对象向量
TheLog Session Bean设计
TheLog bean
主要实现对日志(借书记录)的各项操作,提供多种获得日志的方法(按读者、按图书、按日期、按借还状态等),方法内部实现所有的逻辑处理和转化,返回到远程接口值对象或值对象向量,另外还有如下方法:
方法 功能
public boolean userBorrowBook(String username, String bookISBN) 以一个事务封装读者借书的所有逻辑操作,借书成功返回真值,无法借书返回假值,调用enCode bean对中文进行转码
public boolean userReturnBook(String logbid) 以一个事务封装读者还书的所有逻辑操作,即实现使一笔借书记录销账的功能,调用enCode bean对中文进行转码
public Vector showLogBetweenDays(String dayBegin, String dayEnd) 返回两个日期之间的所有日志,主要利用Calendar类实现
3.4 网络应用层设计
本层本着面向对象思想的封装性、数据模糊性、可重用性等原则设计。
本着系统运行错误在系统中打印(System.out.println)、用户输入和误操作错误导向友好的错误处理页并给出友好的提示的错误处理原则。
每次对会话bean的调用写入系统运行日志文件,默认路径是C:\\booksManagerLog.dat。
CheckValue bean
封装多个静态方法。
可以用于检测某表中某个字段是否已经存在某个值(可用于检测重名用户、重号图书)、检测用户名合法性、检测密码合法性、检测年龄合法性、检测电子邮件合法性、检测数字合法性、检测日期合法性等。
EnCode bean
封装编码转码工作:
html显示转码,例如:将转为,将转为rt;,将数据库中的换行转为html中的换行等等,这样可以屏蔽用户提交文本中的可执行代码。
可重载的中文转码。
密码的加密和解密编码。
JDBCBean bean
封装所有的数据库操作。包括一个带结果集返回的SQL执行方法和一个不带结果集返回的SQL执行方法。
Rank bean
封装4种权限(普通读者、用户管理员、图书管理员、系统管理员)的页面访问,相当于页面加锁功能。
SetUp bean
public static String title="SuperLibrary";//系统名称
public static String dbS="booksManagerDS";//数据库的JNDI名
public static String errorPage="dealError.jsp?theError=";//友好的错误处理页,用get方法传递出错原因
public static String homePage="default.jsp";//默认首页
//权限-------------------------------------------------------------------------
public static String Reader="Reader";//读者
public static String UserAdmin="UserAdmin";//用户管理员
public static String BookAdmin="BookAdmin";//图书管理员
public static String SuperAdmin="SuperAdmin";//系统管理员
//等级-------------------------------------------------------------------------
public static String Undergraduate="Undergraduate";//本科生
public static int UndergraduateRenew=1;//本科生可续借的次数
public static int UndergraduateMaxday=30;//本科生一次可借的天数
public static String Graduate="Graduate";//研究生
public static int GraduateRenew=2;//研究生可续借的次数
public static int GraduateMaxday=45;//研究生一次可借的天数
public static String Teacher="Teacher";//教师
public static int TeacherRenew=3;//教师可续借的次数
public static int TeacherMaxday=60;//教师一次可借的天数
//----------------------------------------------------------------------------
public static int rsPerPage=5;//每页显示记录的数量
public static int minBooks=4;//系统默认的最小借书数
SplitPage bean
将数据记录分页的逻辑实现和页面显示(最简,可在外部由样式表美化)封装在一个bean中,重用时实际只需要传递一个记录集数量的为参数即可,可重用。一般作为session级java bean在页面中被调用,在会话中保存用户对此页面的访问状态,在会话结束之前始终记忆用户访问此页对应的页码。
UserLogin bean
将用户登录的逻辑实现和页面显示(最简,可在外部由样式表美化)封装在一个bean中,包括对用户各种登录情况的处理,可重用。
SearchBook bean
利用JDBC实现模糊查找和按指定类别精确查找图书的功能。
SearchDeadline bean
利用JDBC调用视图实现到期图书的催还功能。
ValidateIMG servlet
动态生成含有随机验证码的图片,在生成图片的同时将验证码写入session中,与用户的登录输入比较。可有效的防止机器人登录。
GetDelete servlet servlet
处理图书、用户、日志的注销操作,根据返回值进行相应页面的跳转。
GetBookSubmit servlet
处理图书的入库和图书信息的修改,根据返回值进行相应页面的跳转。
GetUserSubmit servlet
处理用户的注册和用户信息的修改,根据返回值进行相应页面的跳转。
GetRenewBook servlet
处理用户续借图书的请求(JDBC调用存储过程实现),从系统临时表中读取状态值,根据状态值进行相应页面的跳转。
GetBorrowBook servlet
处理用户的借书请求,将用户借书限额已满、库存为零等错误导向友好的错误页,如果借书成功则跳转到图书信息页面,并给与相应的提示。
GetReturnBook servlet
处理用户的还书请求,如果还书成功则跳转到用户的借书记录页面,并给与相应的提示。
4 程序架构
4.1 程序组织结构
说明:图书搜索和用户登录看作系统外部功能,通过JDBC直接调用数据库,其中用户登录模块封装在一个java bean中,可重用。另外,用户续借图书是通过存储过程实现,从而绕过了使用CMP技术管理事务的实体bean。
本系统其余程序的组织结构严格按照下图实现:
程序组织结构图
4.2 功能权限划分
站点页面地图
权限名称 系统定义字符 权限 可访问页面
普通读者 Reader 查看自己的信息(还书、续借);
修改自己的信息;
查看图书(借书); userModify
userView
booklist
图书管理员 BookAdmin 拥有普通读者的权限;
图书的增删改查;
到期催还; userModify
userView
booklist
bookAdder
bookModify
deadline
用户管理员 UserAdmin 拥有普通读者的权限;
用户的增删改查; userModify
userView
booklist
userRegister
userModify
userList
系统管理员 SuperAdmin 拥有图书管理员和用户管理员的权限;
查看系统日志;
删除系统日志;
系统设置; 包括setupSYS.jsp(系统设置,利用application级java bean控制整个应用程序)在内的所有页面
4.3 WEB程序/页面设计
利用input style="ime-mode:disabled"代码关闭客户端的输入法,实现用户名、密码不能出现中文的问题。
利用onfocus=this.select() onmouseover=this.focus()代码使文本框自动吸附获得焦点,方便用户输入。
利用WMODE="transparent"参数使flash的背景透明,更好的融入网页。
在每页中,利用代码:
IFRAME frameBorder=0 height=88 marginHeight=0 marginWidth=0 scrolling=no src="../iframe/top.htm" width=755 BORDERCOLOR="#000000"/IFRAME
IFRAME frameBorder=0 height=68 marginHeight=0 marginWidth=0 scrolling=no src="../iframe/below.htm" width=755 BORDERCOLOR="#000000"/IFRAME
嵌入上下导航条,使网站导航明确,方便用户浏览。
在网页头部加入代码:
meta HTTP-EQUIV="pragma" CONTENT="no-cache"
meta HTTP-EQUIV="expires" CONTENT="0"
使客户端不缓存网页,保证了客户每次浏览该页都从服务器获得最新的版本,以求正确显示。
提供智能搜索(获得尽可能多的匹配)和精确搜索(获得尽可能精确的匹配)图书,服务器端编程都采用模糊查找的方式。
在客户端用javascript对表单提交进行第一次验码,通过后提交到服务器端,再进行第二次验码,验码包括:用户名是否重复、年龄是不是合适的数字,两次密码输入的是否一致、电子邮件是否合法、密码是否太短、用户名是否太短、用户名密码是否为空等等。
利用随机生成JPG图片验证码的方法,防止机器人登录。
在页面中使用session级java bean实现分页,在会话中保存用户对此页面的访问状态,在会话结束之前始终记忆用户访问此页对应的页码。
在页面中使用application级java bean实现安全的系统设置,当服务器启动后,即可对系统运行参数进行应用程序级的设置,只要服务器不关闭,此设置始终有效且作用于所有用户,如果设置不慎造成系统错误或想恢复系统默认设置,则只需重新启动服务器即可。
在对会话bean的调用包ejbClient中,创建系统运行日志,通过包中的writeF类写入web服务器的C:\\booksManagerLog.dat中,可做查询用。
4.4 本系统实现的功能
确定图书的基本信息,有书名、作者、出版日期、当前借阅状态等属性
系统的使用者包括读者、图书管理员、用户管理员、系统管理员四种
读者可以查询图书;图书管理员可以完成图书管理、借阅管理;读者管理员可以完成读者管理的功能;系统管理员可以使用系统的所有功能
图书管理:新书登记,图书查询,图书注销;
借阅管理:借书,还书,查询到期读者
读者管理:增加读者、删除读者、查询读者、读者类别管理(设置研究生,本科生,教师的可借册数,可借天数,可续借次数等)
系统管理:系统管理员使用,包括用户权限管理(增加用户,删除用户,密码修改等),系统借书日志,系统运行日志,系统设置等功能
页面输入有验码,密码存取有加密
图书到期催还
体现分层设计思想,使用MVC架构
实现了多个Beans,Bean之间实现了对应的关系
使用了EJB QL,事务控制等
使用了jsp-sessionBean-entityBean-数据库模式
数据库使用了触发器和存储过程等一些高级技术
create database db
use db
create table 借阅等级信息(
借阅等级 int primary key,
最长借阅时间 int,
最大借阅数量 int,
)
insert into 借阅等级信息 values
(0, 30, 10),
(1, 60, 20),
(2, 90, 30),
(3, 120, 40)
create table 读者信息(
姓名 char(15) not null,
证件号 char(12) primary key,
借阅等级 int default 0,
累计借书 int default 0,
foreign key(借阅等级) references 借阅等级信息(借阅等级)
)
insert into 读者信息(姓名, 证件号, 借阅等级) values
('张三', '541607120165', 1),
('李四', '541707010185', 3),
('王五', '541707120165', 1),
('赵六', '541505980268', 2),
('孙七', '541407010169', 0),
('周八', '541307010489', 1)
create table 出版社信息(
出版社 varchar(20) primary key,
地址 varchar(25),
联系电话 char(7)
)
insert into 出版社信息 values
('清华大学出版社', '北京', '4979421'),
('晟威出版社', '天津', '5564130'),
('南海出版公司', '海南', '4984910'),
('上海文艺出版社', '上海', '6640239')
create table 图书信息(
索书号 char(15) primary key,
作者 char(15),
书名 char(15),
出版社 varchar(20),
出版时间 date,
foreign key(出版社)references 出版社信息(出版社)
)
insert into 图书信息 values
('b12987', '严蔚敏', '数据结构', '清华大学出版社', '2012-02-06'),
('b97894', '东野圭吾', '幻夜', '南海出版公司', '2004-08-02'),
('b16546', '吴玉华', '物理实验教程', '清华大学出版社', '2013-05-15'),
('b89490', '张雪峰', '考研指点', '晟威出版社', '2016-12-12'),
('b56400', '郏宗培', '纸上寻仙记', '上海文艺出版社', '2011-02-05')
create table 单本图书信息(
条码号 char(7) primary key check(len(条码号) = 7),
索书号 char(15),
馆藏地 varchar(40),
书刊状态 varchar(6) check(书刊状态 in ('可借', '借出', '非可借')),
历史借阅量 int default 0,
foreign key(索书号)references 图书信息(索书号)
)
insert into 单本图书信息(条码号, 索书号, 馆藏地, 书刊状态) values
('t987628', 'b97894', '三楼A8', '借出'),
('t594805', 'b97894', '二楼C7', '可借'),
('t984910', 'b89490', '五楼A2', '借出'),
('t940566', 'b12987', '负一楼D3', '借出')
create table 借阅信息(
借阅号 char(6) primary key,
借阅时间 date,
归还时间 date,
图书条码号 char(7),
借阅人证件号 char(12),
foreign key(图书条码号) references 单本图书信息(条码号),
foreign key(借阅人证件号) references 读者信息(证件号)
)
create table 评论信息(
评论号 char(8) primary key,
评分 numeric(2, 1),
内容 varchar(200),
评论时间 date,
评论者id char(12),
索书号 char(15),
foreign key(索书号)references 图书信息(索书号),
foreign key(评论者id)references 读者信息(证件号)
)
insert into 评论信息 values
('p12391', 8.9, '很有趣', '2015-06-24', '541707010185', 'b97894'),
('p98523', 7.8, '受益颇多', '2016-05-22', '541307010489', 'b89490'),
('p94606', 6.8, '完全看不懂orz', '2017-05-02', '541607120165', 'b12987')
create table 主题词信息(
ID char(8) primary key,
类别 char(15),
索书号 char(15),
foreign key(索书号)references 图书信息(索书号)
)
insert into 主题词信息 values
('z64400', '计算机', 'b12987'),
('z95410', '物理', 'b16546'),
('z98500', '考研', 'b89490'),
('z64165', '推理\悬疑', 'b97894'),
('z69850', '仙侠', 'b56400')
use db
go
create trigger trigger1
on 借阅信息
after insert
as
begin
update 读者信息 --更改读者累计借书量
set 累计借书 = 累计借书 + 1
from 读者信息, inserted
where 读者信息.证件号 = inserted.借阅人证件号
update 单本图书信息 --更改图书状态
set 单本图书信息.书刊状态 = '借出'
from inserted, 单本图书信息
where inserted.图书条码号 = 单本图书信息.条码号
update 单本图书信息
set 历史借阅量 = 历史借阅量 + 1 --更改图书历史借阅量
from inserted, 单本图书信息
where inserted.图书条码号 = 单本图书信息.条码号
end
insert into 借阅信息 values
('j13488', '2018-05-01', '2018-08-01', 't987628', '541407010169')
insert into 借阅信息 values
('j14910', '2016-12-11', '2017-01-25', 't984910', '541607120165')
insert into 借阅信息 values
('j97890', '2018-05-14', '2018-06-14', 't940566', '541607120165')
go
create view view_1(图书条码, 借阅者姓名, 编号, 借阅时间, 应还时间)
as
select 图书条码号, 姓名, 证件号, 借阅时间, 归还时间
from 借阅信息, 读者信息
where 借阅信息.借阅人证件号 = 读者信息.证件号 and 归还时间 getdate()
go
create view view_2(图书条码, 历史总借阅量)
as
select 条码号, 历史借阅量
from 单本图书信息, 图书信息
where 单本图书信息.索书号 = 图书信息.索书号 and 书名 = '幻夜'
go
create view view_3(类别, 图书条码, 历史总借阅量)
as
select 类别, 条码号, 历史借阅量
from 单本图书信息, 图书信息, 主题词信息
where 主题词信息.索书号 = 图书信息.索书号 and 图书信息.索书号 = 单本图书信息.索书号 and 类别 = '考研'
go
create view view_4(读者编号, 条码, 图书名称, 应还日期)
as
select 借阅人证件号, 图书条码号, 书名, 归还时间
from 单本图书信息, 图书信息, 借阅信息
where 借阅信息.图书条码号 = 单本图书信息.条码号 and 单本图书信息.索书号 = 图书信息.索书号
and 归还时间 getdate() and 借阅人证件号 = '541607120165'
go
create view view_5(读者编号, 图书条码, 图书名称, 借阅日期, 归还日期)
as
select 借阅人证件号, 图书条码号, 书名, 借阅时间, 归还时间
from 单本图书信息, 图书信息, 借阅信息
where 借阅信息.图书条码号 = 单本图书信息.条码号 and 单本图书信息.索书号 = 图书信息.索书号
and 借阅人证件号 = '541607120165'
go
create view view_6(读者编号, 图书名称, 评论时间, 评论内容)
as
select 评论者id, 书名, 评论时间, 内容
from 借阅信息, 单本图书信息, 评论信息, 图书信息
where 借阅信息.图书条码号 = 单本图书信息.条码号 and 单本图书信息.索书号 = 评论信息.索书号
and 评论信息.索书号 = 图书信息.索书号 and 评论者id = '541607120165'
go
create view view_7(出版社名称, 图书名称, 出版时间)
as
select top 100 percent 出版社信息.出版社, 书名, 出版时间
from 出版社信息, 图书信息
where 出版社信息.出版社 = 图书信息.出版社
order by 出版时间 asc
--执行
select * from view_1
select * from view_2
select * from view_3
select * from view_4
select * from view_5
select * from view_6
select * from view_7 order by 出版时间 asc
扩展资料:
数据库模型:
对象模型
层次模型(轻量级数据访问协议)
网状模型(大型数据储存)
关系模型
面向对象模型
半结构化模型
平面模型(表格模型,一般在形式上是一个二维数组。如表格模型数据Excel)
架构
数据库的架构可以大致区分为三个概括层次:内层、概念层和外层。
内层:最接近实际存储体,亦即有关数据的实际存储方式。
外层:最接近用户,即有关个别用户观看数据的方式。
概念层:介于两者之间的间接层。
数据库索引
主条目:数据库索引
数据索引的观念由来已久,像是一本书前面几页都有目录,目录也算是索引的一种,只是它的分类较广,例如车牌、身份证字号、条码等,都是一个索引的号码,当我们看到号码时,可以从号码中看出其中的端倪,若是要找的人、车或物品,也只要提供相关的号码,即可迅速查到正确的人事物。
另外,索引跟字段有着相应的关系,索引即是由字段而来,其中字段有所谓的关键字段(Key Field),该字段具有唯一性,即其值不可重复,且不可为"空值(null)"。
例如:在合并数据时,索引便是扮演欲附加字段数据之指向性用途的角色。故此索引为不可重复性且不可为空。
数据库操作:事务
主条目:数据库事务
事务(transaction)是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。
事务的并发性是指多个事务的并行操作轮流交叉运行,事务的并发可能会访问和存储不正确的数据,破坏交易的隔离性和数据库的一致性。
网状数据模型的数据结构 网状模型 满足下面两个条件的基本层次联系的集合为网状模型。 1. 允许一个以上的结点无双亲; 2. 一个结点可以有多于一个的双亲。
参考资料来源:百度百科——数据库
完整的C语言图书管理系统
#include stdlib.h
#include stdio.h
#include conio.h
#include "graphics.h"
#include "math.h"
#define m 1
struct data
{ int year;
int month;
int day;
};
struct ReaderNode
{
char num[20];
struct data bro;
struct data back;
};
struct BookNode
{
char title[15];
char writer[15];
int currentnum;
int totalnum;
char brief[30];
struct ReaderNode reader[20];
};
struct TreeNode
{
int n;
struct TreeNode *prt;
int key[2*m];
struct BookNode *rec[2*m];
struct TreeNode *link[2*m+1];
};
struct BookNode *InputNode();
struct TreeNode *mbsearch(struct TreeNode *bth,int x,int *k,int *flag);
struct TreeNode *mbinsert(struct TreeNode *bth);
struct TreeNode *mbdel(struct TreeNode *bth);
void OutputNode(struct TreeNode *bth);
void borrow(struct TreeNode *bth);
void payback(struct TreeNode *bth);
char menu(void);
struct TreeNode *mbsearch(struct TreeNode *bth,int x,int *k,int *flag)
{
struct TreeNode *p,*q;
p=bth; *flag=0; q=p;
while( (p!=NULL) (*flag==0) )
{
*k=1;q=p;
while( (*k q-n) ( q-key[*k-1] x) ) *k=*k+1;
if( q-key[*k-1]==x) *flag=1;
else if( ( *k==q-n ) ( q-key[*k-1] x) ) {p=q-link[*k];p-prt=q;}
else { p=q-link[*k-1]; p-prt=q;*k=*k-1;}
}
return(q);
}
struct TreeNode *mbinsert(struct TreeNode *bth)
{
int flag,j,k,t;
int y,x,z;
struct TreeNode *p,*q,*u,*s;
struct BookNode *r,*l;
clrscr();
printf("\n\tPlease input the book you want to insert: ");
scanf("%d",x);
q=mbsearch(bth,x,k,flag);
if(flag==1)
{
printf("\n\tHas %d this kind of book,do you want to add another?(y/n)\n",(q-rec[k-1])-totalnum);
z=getch();
if(z=='y'||z=='Y')
{
(q-rec[k-1])-totalnum++; (q-rec[k-1])-currentnum++;
printf("\n\tNow total has %d this kind of book,",(q-rec[k-1])-totalnum);
printf("\n\tand current has %d in the library.",(q-rec[k-1])-currentnum);
}
return(bth);
}
r=InputNode(bth);
if(bth==NULL)
{
bth=p=(struct TreeNode *)malloc(sizeof(struct TreeNode));
p-n=1; p-key[0]=x; p-rec[0]=r;p-prt=NULL;
for(j=1;j=2*m+1;j++) p-link[j-1]=NULL;
return(p);
}
p=NULL; t=0;
while(t==0)
{
if(k==q-n) {y=x;l=r;u=p;}
else
{
y=q-key[q-n-1]; l=q-rec[q-n-1];u=q-link[q-n];
for(j=(q-n)-1; j=k+1; j--)
{
q-key[j]=q-key[j-1];q-rec[j]=q-rec[j-1];q-link[j+1]=q-link[j];
}
q-key[k]=x;q-rec[k]=r;q-link[k+1]=p;
if(p!=NULL) p-prt=q;
}
if(q-n2*m)
{
q-n=(q-n)+1;
t=1;
q-key[(q-n)-1]=y; q-rec[(q-n)-1]=l; q-link[q-n]=u;
if(u!=NULL) u-prt=q;
}
else
{
p=(struct TreeNode *)malloc(sizeof(struct TreeNode));
p-n=m; q-n=m; p-prt=q-prt;
x=q-key[m];r=q-rec[m];
for(j=1;j=m-1;j++)
{
p-key[j-1]=q-key[m+j];p-rec[j-1]=q-rec[m+j];p-link[j-1]=q-link[m+j];
if(q-link[m+j]!=NULL) (q-link[m+j])-prt=p;
}
p-link[m-1]=q-link[2*m];
p-link[m]=u;
p-key[m-1]=y;
p-rec[m-1]=l;
if(u!=NULL) u-prt=p;
for(j=m+2;j=2*m+1;j++)
{
q-link[j-1]=NULL;p-link[j-1]=NULL;
}
if(q-prt==NULL)
{
s=(struct TreeNode *)malloc(sizeof(struct TreeNode));
s-key[0]=x; s-rec[0]=r;
s-link[0]=q; s-link[1]=p;
s-n=1; s-prt=NULL; q-prt=s; p-prt=s;
for(j=3;j=2*m+1;j++) s-link[j-1]=NULL;
bth=s; t=1;
}
else
{
q=q-prt; k=1;
while((k=q-n)(q-key[k-1]x)) k=k+1;
k=k-1;
}
}
}
return(bth);
}
struct TreeNode *mbdel(struct TreeNode *bth)
{
int flag,j,k,t;
int x,y;
struct TreeNode *u,*s,*p,*q;
struct BookNode *r,*l;
clrscr();
printf("\n\tPlease input the book you want to delete: ");
scanf("%d",x);
q=mbsearch(bth,x,k,flag);
if(flag==0) { printf("\n\tThe book is not exist!\n"); return(bth);}
p=q-link[k];
if(p!=NULL)
{
while(p-link[0]!=NULL) p=p-link[0];
q-key[k-1]=p-key[0];
q-rec[k-1]=p-rec[0];
k=1;q=p;
}
for(j=k;j=q-n-1;j++)
{
q-key[j-1]=q-key[j];
q-rec[j-1]=q-rec[j];
}
q-n=q-n-1;
while ((q!=bth)(q-nm))
{
p=q-prt;j=1;
while(p-link[j-1]!=q) j=j+1;
if((j=p-n)((p-link[j])-nm))
{
s=p-link[j];
y=s-key[0];
l=s-rec[0];
u=s-link[0];
for(k=1;k=s-n-1;k++)
{
s-key[k-1]=s-key[k];
s-rec[k-1]=s-rec[k];
s-link[k-1]=s-link[k];
}
s-link[s-n-1]=s-link[s-n];
s-link[s-n]=NULL;
s-n=s-n-1; q-n=q-n+1;
q-key[q-n-1]=p-key[j-1];
q-rec[q-n-1]=p-rec[j-1];
q-link[q-n]=u;
p-key[j-1]=y;
p-rec[j-1]=l;
if(u!=NULL) u-prt=q;
}
else if((j1)((p-link[j-2])-nm))
{
s=p-link[j-2];
q-n=q-n+1;
q-link[q-n]=q-link[q-n-1];
for(k=q-n-1;k=1;k--)
{
q-key[k]=q-key[k-1];
q-rec[k]=q-rec[k-1];
q-link[k]=q-link[k-1];
}
q-key[0]=p-key[j-2];
q-rec[0]=p-rec[j-2];
u=s-link[s-n];
q-link[0]=u;
if(u!=NULL) u-prt=q;
p-key[j-2]=s-key[s-n-1];
p-rec[j-2]=s-rec[s-n-1];
s-link[s-n]=NULL;
s-n=s-n-1;
}
else
{
if(j==p-n+1)
{ q=p-link[j-2]; s=p-link[j-1]; j=j-1;}
else s=p-link[j];
q-key[q-n]=p-key[j-1];
q-rec[q-n]=p-rec[j-1];
t=q-n+1;
for(k=1;k=s-n;k++)
{ q-key[t+k-1]=s-key[k-1];
q-rec[t+k-1]=s-rec[k-1];
u=s-link[k-1];
q-link[t+k-1]=u;
if(u!=NULL) u-prt=q;
}
u=s-link[s-n]; q-link[t+s-n]=u;
if(u!=NULL) u-prt=q;
q-n=2*m;
free(s);
for(k=j;k=p-n-1;k++)
{
p-key[k-1]=p-key[k];
p-rec[k-1]=p-rec[k];
p-link[k]=p-link[k+1];
}
p-n=p-n-1; s=q; q=p;
}
}
if((q==bth)(q-n==0))
{ free(bth); bth=s; bth-prt=NULL;
if(s-n==0) {bth=NULL; free(s); }
}
printf("\n\tThe book has been delete !");
return(bth);
}
struct BookNode *InputNode()
{
struct BookNode *p;
int i;
p=(struct BookNode *)malloc(sizeof(struct BookNode));
clrscr();
fflush(stdin);
printf("\n\tInput the title: ");
gets(p-title);
printf("\n\tInput the writer: ");
gets(p-writer);
printf("\n\tInput the book current amount: ");
scanf("%d",p-currentnum);
printf("\n\tInput the book total amount: ");
scanf("%d",p-totalnum);
fflush(stdin);
printf("\n\tInput the book brief instruction: ");
gets(p-brief);
for(i=0;i20;i++)
(p-reader[i]).num[0]='\0';
return(p);
}
void OutputNode(struct TreeNode *bth)
{
struct TreeNode *q;
struct BookNode *p;
int k;
int x;
int flag;
clrscr();
printf("\n\tPlease input the book you want to search: ");
scanf("%d",x);
q=mbsearch(bth,x,k,flag);
if(flag==1)
{
p=q-rec[k-1];
printf("\n\tTitle: %s",p-title);
printf("\n\tWriter: %s",p-writer);
printf("\n\tCurrentAmount: %d",p-currentnum);
printf("\n\tTotalAmount: %d",p-totalnum);
printf("\n\tBriefIntroduction: %s\n",p-brief);
}
else printf("\n\tThis book is not exist!");
}
void borrow(struct TreeNode *bth)
{
struct TreeNode *q;
struct BookNode *p;
struct ReaderNode *r;
int i,k, x, flag,t;
clrscr();
printf("\n\tPlease input the book you want to borrow: ");
scanf("%d",x);
q=mbsearch(bth,x,k,flag);
if(flag==1)
{
p=q-rec[k-1];
printf("\n\tDo you want this book ?(y/n)");
printf("\n\tTitle: %s",p-title);
printf("\n\tWriter: %s",p-writer);
printf("\n\tCurrentAmount: %d",p-currentnum);
printf("\n\tTotalAmount: %d",p-totalnum);
printf("\n\tBriefIntroduction: %s",p-brief);
t=getch();
if(t=='y'||t=='Y')
{
if( (p-currentnum)==0) printf("\n\tSorry,this book has all borrow out...");
else
{
clrscr();
for(i=0;i20;i++) if( (p-reader[i]).num[0]=='\0') break;
printf("\n\tPlease input your certificate number: ");
scanf("%s",(p-reader[i]).num);
printf("\n\tPlease input the borrow data: ");
printf("\n\tYear: ");
scanf("%d",((p-reader[i]).bro.year));
printf("\tMonth: ");
scanf("%d",((p-reader[i]).bro.month));
printf("\tDay: ");
scanf("%d",((p-reader[i]).bro.day));
printf("\n\tPlease input the payback data: ");
printf("\n\tYear: ");
scanf("%d",((p-reader[i]).back.year));
printf("\tMonth: ");
scanf("%d",((p-reader[i]).back.month));
printf("\tDay: ");
scanf("%d",((p-reader[i]).back.day));
p-currentnum--;
printf("\n\tYou have borrow the book.");}
}
}
else printf("\n\tThis book is not exist!");
}
void payback(struct TreeNode *bth)
{
struct TreeNode *q;
struct BookNode *p;
int i,k, x, flag,t,j;
int year,month,day,d;
float pay;
char temp[20];
clrscr();
printf("\n\tPlease input the book you want to payback: ");
scanf("%d",x);
q=mbsearch(bth,x,k,flag);
if(flag==1)
{
p=q-rec[k-1];
printf("\n\tDo you want to payback this book ?(y/n)");
printf("\n\tTitle: %s",p-title);
printf("\n\tWriter: %s",p-writer);
printf("\n\tCurrentAmount: %d",p-currentnum);
printf("\n\tTotalAmount: %d",p-totalnum);
printf("\n\tBriefIntroduction: %s",p-brief);
t=getch();
if(t=='y'||t=='Y')
{
if( (p-currentnum) =(p-totalnum) )
printf("\n\tYou want to offer a more book ??\n");
else
{
clrscr();
printf("\n\tPlease input your certificate number: ");
scanf("%s",temp);
j=0;
for(i=0;i20;i++)
{
if(! (strcmp(temp,(p-reader[i]).num))) {j=1;break;}
}
if(j==0) {printf("\n\tYou haven't borrow this book.");return;}
printf("\n\tToday is:");
printf("\n\tYear: ");
scanf("%d",year);
printf("\tMonth: ");
scanf("%d",month);
printf("\tDay: ");
scanf("%d",day);
d=0;
if(year(p-reader[i]).back.year) d=1;
if(year=(p-reader[i]).back.year month(p-reader[i]).back.month) d=1;
if(year=(p-reader[i]).back.year month=(p-reader[i]).back.month day(p-reader[i]).back.day) d=1;
if(d==0)
{
clrscr();
pay=(year-(p-reader[i]).back.year)*365+(month-(p-reader[i]).back.month)*30+(day-(p-reader[i]).back.day);
printf("\n\tYou borrow this book is in %d-%d-%d",(p-reader[i]).bro.year,(p-reader[i]).bro.month,(p-reader[i]).bro.day);
printf("\n\tYou should pay it back in %d-%d-%d",(p-reader[i]).back.year,(p-reader[i]).back.month,(p-reader[i]).back.day);
printf("\n\tToday is %d-%d-%d",year,month,day);
printf("\n\n\tSo you have go out the payback day");
printf("\n\tYou have to pay %2.1f Yuan.",0.1*pay);
}
(p-reader[i]).num[0]='\0';
p-currentnum++;
printf("\n\tYou have payback the book.");
}
}
}
else printf("\n\tYou want to payback an inexistence book ???");
}
donghua()
{int graphdriver=VGA;
int graphmode=VGAHI;
int i,j;
registerbgidriver(EGAVGA_driver);
initgraph(graphdriver,graphmode,"");
clrscr();
for(i=0;i=150;i+=5)
{setcolor(i);
textbackground(RED);
settextstyle(0,0,2);
outtextxy(100,i+140,"Liberary management System");
delay(10000000);
clrscr();
}
setcolor(RED);
outtextxy(50,200,"Loading");
delay(100000000000);
outtextxy(50,200,"Loading.");
delay(100000000000);
outtextxy(50,200,"Loading..");
delay(100000000000);
outtextxy(50,200,"Loading...");
delay(100000000000);
outtextxy(50,200,"Loading....");
delay(100000000000);
outtextxy(50,200,"Loading.....");
delay(100000000000);
outtextxy(50,200,"Loading......");
delay(100000000000);
outtextxy(50,200,"Loading.......");
delay(100000000000);
outtextxy(50,200,"Loading........");
delay(100000000000);
outtextxy(50,200,"Loading.........");
delay(100000000000);
outtextxy(50,200,"Loading..........");
delay(100000000000);
outtextxy(50,200,"Loading...........");
outtextxy(50,200,"Loading............");
delay(100000000000);
for(i=0;i=10;i++)
delay(100000000000);
clrscr();
}
char menu(void)
{
clrscr();
window(1,1,80,25);
textmode(MONO);
textbackground(BLACK);
textcolor(5);
printf("\n\t ****************************************************");
printf("\n\t ***** Welcome to Liberary management System *****");
printf("\n\t ****************************************************");
printf("\n\t ****************************************************");
printf("\n\t *1.Add a book *");
printf("\n\t ****************************************************");
printf("\n\t *2.Delete a book *");
printf("\n\t ****************************************************");
printf("\n\t *3.Search a book *");
printf("\n\t ****************************************************");
printf("\n\t *4.Borrow a book *");
printf("\n\t ****************************************************");
printf("\n\t *5.Payback a book *");
printf("\n\t ****************************************************");
printf("\n\t *0.exit *");
printf("\n\t ****************************************************");
printf("\n\t please select: ");
return getch();
}
bofangdonghua()
{int graphdriver=VGA;
int graphmode=VGAHI;
int i,j;
char c;
registerbgidriver(EGAVGA_driver);
initgraph(graphdriver,graphmode,"");
/*************shi fou bo fang dong hua?**************/
printf:{setcolor(RED);
settextstyle(3,0,5);
outtextxy(100,30,"bo fang dong hua?");
outtextxy(150,80,"Yes");
outtextxy(300,80,"No");
c=getch();
if(c=='Y'||c=='y')
{donghua();
menu();
}
else
if(c=='N'||c=='n')
menu();
else
{setcolor(GREEN);
settextstyle(3,0,8);
outtextxy(200,240,"Error!");
delay(10000000000);
clrscr();
goto printf;
}
}
/**************************************/
}
void main()
{
char c,t;
int x;
int k,flag,p=1;
struct TreeNode *bth=NULL;
bofangdonghua();
while(1)
{
c=menu();
putch(c);
getch();
switch(c)
{
case '1': bth=mbinsert(bth);
break;
case '2': bth=mbdel(bth);
break;
case '3': OutputNode(bth);
break;
case '4': borrow(bth);
break;
case '5': payback(bth);
break;
case '0': clrscr();
printf("\n\tDo you want to return ?(y/n)");
t=getch();
if(t=='y'||t=='Y') exit(0);
break;
defult :break;
}
printf("\n\tPress any key to the main menu....");
getch();
}
}