自取:https://github.com/1098301679/JavaWeb-
嘿嘿,插这么多图太不容易了
那个,打不开的就多打几次就开了,坚持坚持,毕竟github嘛
这是一个图书管理系统(老师布置的题目),不要问我问什么不用框架,因为奇怪的老师不让用任何框架,所以用原生的JavaWeb写的,所有的前后端代码都是自己写的,很适合刚入门的新手学习,之所以没有用JavaScript是因为觉得没必要,C3的过渡和动画足以实现很多动态效果,模板引擎用的JSP
项目目录结构一览图(下面有具体的每部分的作用的讲解)
一、采用的工具与技术栈
二、图书管理系统数据库的设计
三、成品项目的目录结构展示与说明
四、项目实现的相关信息
五、已有缺陷和不足的分析
六、课程设计收获
七、课程设计后的体会与建议
前端页面设计涉及技术:html5+css3
后端开发设计技术:jsp+servlet+javaBean+jdbc+dao
模板引擎:jsp(el与jstl)
服务器与java版本:Tomcat8.5 java12
开发与调试工具:Eclipse IDE 2020-03 Chorme MySQL Navicat
1.数据库管理系统以及数据库可视化工具的选择
数据库管理系统:mysql数据库管理系统
数据库可视化工具:Navicat for MySQL
2.数据库表关系的分析说明
为了减少表的数据冗余,达到数据库设计的三范式,就要避免表设计时候出现的非主键字段的部份依赖与传递依赖,实体性之间是多对多的联系我们就可以采取三张表的设计,关机表两个外键,如果是一对多,我们可以设计两张表,多方的那张表加外键。
3.数据库以及数据库中表的创建
在mysql中建立了一个名为homework的数据库用来存放与本系统相关的表的信息,所有的表都不采用业务主键,主键只是为了唯一标识表中的一条记录,这里采用的是id作为主键,并且设置为自动递增,以后再见到就不一一描述,所有表的信息如下图所示:
接下来具体介绍该数据库中的每一张表的作用与表之间的关系
username:管理员账号的用户名
password:管理员账号的密码
② user表
由于本系统主要是针对于学校的图书馆里系统,所以在该系统中外校人员以及无关人等不可以申请账户来借书等操作,只有在校学生可以申请账号,所以此表中Sno字段引用的student表中的Sno作为外键(具体看student表)
Sno:用户的学生证号
username:用户账号的用户名
password:用户账号的密码
③ book表
Bname: 图书名称
Bauthor : 图书作者
Bprice: 图书价格
Bnum: 图书数量
Bshelf: 所属书架 引用的bookshelf表中的no作为外键
Bremark: 图书简介
④ bookshelf表
no: 书架编号
area: 占地面积
location: 书架位置
type: 书籍类型
remark: 书架简介
⑤ student表
Sno: 学生证号
Sname: 学生姓名
Sage: 学生年龄
Ssex: 学生性别
Stel: 学生电话
Smajor: 学生专业 引用major表中的Mno字段作为外键
Mno: 专业编号
Mname: 专业名称
Mdept:“ 所属院系 引用department表中的Dno作为外键
⑦ department表
Dno: 院系编号
Dname: 院系名称
⑧ notice表
此表是用来做消息通知的,是为了迎合后来的收发邮件。管理员发通知等功能
sender: 消息的发送方
receiver: 消息的接收方
message: 消息的主内容
time: 消息发送时间
注:time是用varchar存的,在具体业务中是主要使用SimpleDateFormat类的 format方法与java.util.Date和java.sql.Date类来进行具体的业务操作
⑨ book__appointment_relation
Sno: 学生证号 引用student表中的Sno作为外键
Bno: 图书编号 引用book表中的Bno作为外键
⑩ student_book_realtion
此表主要用于记录每个用户的借书信息
Sno: 学生证号
Bno: 图书编号
time: 借书时间
renew: 是否续借 0表示未续借,1表示已续借 只能续借一次 一次15天
⑪ student_borrow_relation
此表主要用于记录每个用户的借书状态
Sno: 学生证号
num: 已借数量 最多可以借阅8本,超过状态发生改变将不能再借
state: 目前状态 0表示不可借阅,1表示可以借阅
⑫ student_fine_relation
此表主要用于记录每个用户的罚款状态
Sno: 学生证号
money: 罚款金额
项目遵循了软甲开发的三层架构的设计,表现层(servlet,jsp与web浏览器等)用于展示数据,业务层(service)用于处理业务需求,持久层(dao)用于完成与数据库的交互
具体的功能演示等请看录制的视频介绍,这里只给出一些实现的细节与界面的截图
① BeanFactory类的细节
通过类加载器获取指定资源properties资源的输入流,加载解析配置文件中的内容,反射创建类的实例对象并且存入到容器中,这里的容器采用的Map,然后其它地方要用的时候。就可以调用BeanFactory类的静态方法getBean来通过key获取实例对象。
注意service所有类的实例化的时机必须要在dao之后,因为service服务层要调用持久层,必须要掌控(依赖)持久层的对象,而持久层对象又是通过容器注入的,所以要先实例化service层再实例化dao层
② ProxyFactory类
该类实现了InvocationHanlder接口,自己实现invoke方法,在创建动态代理对象的时候将自己传入当作第三个参数,该类的属性proxyObject就是具体的要代理的对象,返回的经过Proxy.newProxyInstance方法创建的代理对象将会继承Proxy类实现与被代理对象实现的相同的接口,这样返回的对象的方法在执行时候就会经过InvocationHandler实例的invoke方法的拦截,即会加上了其中(在这里是事务控制)的功能。
③ web.xml
在不使用框架的情况下,一开始我们被该如何在同一个类中接收多个客户端发送的不同的请求,难道要写很多个servlet一个一个的来处理吗?这显然不是一个很好的办法,于是通过百度我了解了怎样让一个servlet处理多个请求,这里的多个请求是同一类请求,然后通过request.getRequserURI()方法来获取请求的url,然后再截取 / 获取请求方法名(请求的具体描述),最后根据if,else判断就可以实现一个servlet处理同一类请求。而这些都是配置在web.xml里面的,下面是web.xml的展示
首先是访问本项目的欢迎页,这个不用多说
比如LoginController类就是专门处理项目下的以login开头的所有同类请求
很多,这里就不一一截图了,一个servlet控制器处理一类请求
④ dao层的实现细节
持久层是与我们的数据库打交道的,所以避免不了要查数据库,查数据库的具体方法都是从request域或者session域中取得的,然后与数据库交互的话增删改比较好说,就是查询的DQL语句有时为了展示的数据丰富要进行多表联查,要进行分页sql的编写。sql语句就会比较长一些,而且后来加了通信等功能没有新写实现类,与借还信息dao类写在一起,导致这个类代码比较多,有点沉重
下面是几个dao的查询方法实现的示例
例如学生查询所有预约的图书与管理员查询某学生借书信息方法:
有好多方法与日期交互有关,主要用以下两个Date类与SimpleDateFormat处理
⑤ 页面的jsp编写的思想(el与jstl的使用)
jsp作为一种模板引擎,同freemarker,thymeleaf一样,作用就是我们来写一个页面的模板,比如有些值是动态的,我们写一些表达式,而这些值从哪里来呢??我们来组装一些数据把页面模板和数据交给我们的模板引擎,模板引擎 按照我们的数据帮我们把表达式解析,填充到我们指定的位置,最终生成一个我们想要的内容给我们写回相应体,浏览器渲染后生成页面
不同模板引擎的思想都是一样的,就是语法可能不太一样jsp的el即expression language 是jsp的表达式语言,jstl是el的扩充,前面都有提到过
下面给出两个具体el与jstl来解析数据动态生成页面的示例:
篇幅原因不演示太多,具体请看源码
⑥ 前端界面展示
1.登录界面(动态提示输入错误信息)注意:退出时要销毁session
2.注册界面
3.登录后管理员页面模板与相应操作页面
4.登录后用户页面模板与相应操作页面
注意会根据不同用户动态生成要显示的信息
所有按钮都可以点击发送请求,进入相应的数据展示页面
系统反馈界面
学生发邮件界面(qq发邮件需要知道对方准确邮箱号,这里需要知道学号,如果需要的话也可以考虑扩充加好友的功能)
页面就先展示到这里
没有实现拦截器以及过滤器等功能并在web.xml中配置,这会导致用户可以直接输入资源的请求路径直接访问后台页面,虽然没有经过登录session域中不会保存用户的信息以致于他们不能进行操作,但这总归是不好的。
student表的学号在数据库中使用的int类型存储,上限是2的31次方-1即2147483647,当时考虑到本校的学生学号全是201xxxxxxx类型,所以就用的int类型存储,好像只能存储到47年,后来发现的时候以及改不太了了(需要重建),因为很多表都引用的外键,然后业务中也造成了一些转型麻烦
修改密码,进行通信的界面信息略少
管理员对一本书操作后如果不是第一页的书籍,操作完会跳回第一页,学生 也是,因为书籍比较多,所以用了分页SQL,一页显示固定本数的书。其他 的比如院系,专业,书架等数据还比较少,暂时也不用考虑分页
5.BeanFactory借鉴了一下IOC的思想,用到了,但是ProxyFactory没有用上 因为在业务逻辑编写的时候没有用到类似于转账等需要事务控制的功能。
6.种种原因没有加上加好友的功能,因为29号视频已经录完了,再加的话要改 动很多东西,(加上的话在有充值功能就可以进行转账就可以用事务控制了) 后期也不会对这个课设进行维护,所以感觉也没有必要加
本次课程设计,按照老师的要求,充分而又系统的统一了web应用开发的基础知识,加强了对基础知识的理解,也同时再次体会到了框架的设计思想以及为什么要出现框架,是因为如果只用这些来开发的时候,耗费在别的方面的精力就会太多,就比如mybatis,hibernate等持久层框架的出现,就封装了很多细节,让我们软件开发者可以使用极简的方式实现我们想要的功能,不用花费精力在注册数据库驱动,获取连接啊,释放资源等等的操作,spring的出现实现了控制反转,将对象的控制权权利转交给容器等。
也体会到了软件设计的总的发展方向就是近一步的封装封装在封装,从原始的开发到ssm,ssh等框架的出现,再到springboot,微服务的兴起,无疑是:just run
另一方面也加强了对前端技术即html5与css3的基础知识的了解与掌握,让自己更好以及更加熟练的了解了其实现的具体细节与过程
进一步的提高了网上解决问题的能力与网上学习能力
通过这次的软件开发,我们巩固了本学期所学习的web开发知识,也大大提高了我们之间的默契与友好的关系,也体会到了从头到尾设计一个网站所带来的乐趣,进一步的熟悉了网站的整个的开发流程,更加深入的了解了web开发的BS架构,以及浏览器与服务器之间交互的细节等等,其它的体会基本与课程设计的收获相同