开发背景:
由于学校规模进一步扩大,学生人数逐年上升,学生信息的管理也变得越来越复杂。为此,学生信息的管理成为了一个急需解决的问题。
本系统采用 C/S 和 B/S 结构,Java 为开发语言,MySQL5.5 为数据库,IDEA 作为开发工具来进行设计与开发。本文档简要阐述了系统的开发背景与开发环境,对系统的构架进行分析,由此划分出各个模块,包括登录模块,学生管理模块,教师管理模块,考勤签到模块,成绩管理模块,选课模块,班级管理模块,系统设置模块。用户可以实现对数据进行录入,删除,修改,查询等操作。从而实现对学生信息进行合理化管理,学生信息的管理本身就是一项繁重的工作任务,面对如此繁杂的任务,如果让个人去管理文档,就会显得费时费力。尤其在对学生信息录入时,任务更加繁重,就管理者本身来说,它是一项任务繁重、时效性较强的系统工作,所以本系统在一定程度上减轻了管理人员的工作任务,让学生信息的管理变得更加轻松,更加高效。
随着高校规模的不断扩大,学生数量也急剧增加,有关学生的各种信息量也成倍增长,各类学生的统计分析工作也越来越困难,面对如此繁杂的工作,为了能够为高校学生信息管理提供一种更加高效实用的管理手段,为学生信息的存储、计算、统计、分析、交流提供一种更加安全快捷的信息平台,并且能够减少大量的人工操作,以及在人工操作中由于人为因素而引起的数据错误,保证学生信息数据的安全性和完整性,使学生管理人员能够轻松,正确无误地完成各项工作,为学生管理工作服务。
目标:
保证信息的准确性和时效性,随时通过计算机对系统进行管理,使得学生信息处于最新状态,保证统计数据和分析的准确。
减轻劳动强度、提高工作效率、增加学生管理的透明度。高校学生管理信息系统可以发挥计算机的强大功能,让管理人员从大量繁琐的手工劳动中解放出来,将单调枯燥的纸张涂写变成灵活的电子信息操作。并充分利用网络优势,加快学校内部学生信息和文档的发布、传送和获取,改善和优化学生工作,使各个部门之间的工作联系紧密、井然有序、清楚明晰,大大减轻工作负担,提高工作效率,增加学生管理的透明度。
降低管理成本,由于采用本系统的原因,使辅导员管理工作一改往日埋在各种表格中的被动局面,基本实现了无纸化办公,根除了很多日常管理中的浪费现象,体现出现代化学生管理的优势。
规范化管理,由于采用了计算机统计分析学生信息,一些原始信息在录入时就必须要求准确录入,这就要求管理人员在提供信息时要准确,同时要求在录入时也要十分认真,这样做是为了将错误降到最低,提高系统工作的准确率,从而实现学生管理工作规范化。
表 1 术语与缩写表
编号 | 缩写 | 英文原文 | 中文含义 |
---|---|---|---|
1 | C/S | Client/Server | 客户机和服务器结构 |
2 | B/S | Browser/Server | 浏览器和服务器结构 |
3 | MVC | Model+View+Controller | 三层架构形式 |
4 | JSON | JavaScript Object Notation | 轻量级的数据交换格式 |
5 | 无 | HttpClient | Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。 |
6 | 无 | ECharts | 一个使用 JavaScript 实现的开源可视化库 |
7 | 无 | JFreeChart | Java 平台上的一个开放的图表绘制类库。 |
图 1 管理员用例图
图 2 教师用例图
图 3 学生用例图
表 2 用例描述表
编号 | 需求名称 | 所含功能 |
---|---|---|
1 | 登录 | 用户输入用户名和密码登录 |
2 | 修改密码 | 用户登录后修改登录密码 |
3 | 退出系统 | 用户退出登录状态 |
4 | 学生添加 | 用户登录后添加新的学生信息 |
5 | 学生列表 | 查看学生信息,并可以对其进行修改或删除 |
6 | 教师添加 | 添加新的教师信息 |
7 | 教师列表 | 查看教师信息,并对其进行修改或删除 |
8 | 班级添加 | 添加新的班级信息 |
9 | 班级列表 | 查看班级信息,并对其进行修改或删除 |
10 | 添加课程 | 添加新的课程信息 |
11 | 课程列表 | 查看课程信息,并对其进行修改或删除 |
12 | 选课管理 | 对学生选课信息进行查看,并对其进行修改或退选 |
13 | 学生签到 | 学生对分发布签到的课程进行签到 |
14 | 签到管理 | 对学生签到情况进行查看、修改 |
15 | 签到统计 | 对学生签到情况进行统计 |
16 | 录入成绩 | 录入学生各科成绩 |
17 | 成绩查看 | 查看学生各科成绩 |
18 | 成绩管理 | 对学生成绩进行修改、删除 |
19 | 成绩统计 | 对录入的学生成绩进行统计 |
20 | 帮助 | 显示制作团队信息 |
方便、简洁、美观、一致,符合大众审美。
响应时间:小于等于 2 秒。
处理速度:达到较快的速度。
并发度:能够支持多台客户端同时提供服务。
非法输入和操作的处理;
用户密码要加密存储;
多个客户端同时登录的问题;
对某些特定的功能的访问权限的限定。
C/S 端系统逻辑架构
Server
采用 Spring+Mybatis 的框架结构
图 4 C/S 端系统逻辑架构图
Client
采用 JavaSwing 来构建用户界面
B/S 端系统架构
Server
采用现在流行的 SpringBoot+Spring Data JPA 的框架结构
图 5 B/S 端系统逻辑架构图(a)
Browser
前端的 HTML 页面采用了 Thymeleaf 模板引擎来进行前后端数据的交互
图 6 B/S 端系统逻辑架构图(b)
CSS 里面放着一些常用的 CSS 样式等,images 是存放项目所用到的图片,js 里面放着一些常用的 js 包等。
客户端向服务器发请求,服务器处理请求并将结果返回客户端;客户端不能直接访问数据库,服务器是两者间的桥梁。
图 7 物理逻辑架构图
C/S 端架构
图 8 C/S 项目目录结构
项目由 com 目录下的代码和 resources 目录下的资源组成的。com 包下的 dao 包是项目的持久层,主要存放着一些与数据库交互的接口,它们负责数据库的增删改查操作;com 包下的 entity 包是项目的实体类包,主要存放着一些实体类,它们负责与数据库的表产生映射关系;com 包下的 service 包是项目的业务层,主要存放着一些业务逻辑的实现和接口类,它们负责项目具体的业务逻辑的实现;com 包下的 utils 包是项目的工具包,主要负责存放项目中用到的各种工具类;com 包下的 view 包是项目的视图层,主要存放着 JavaSwing 中的视图类,它们负责构建用户使用的界面。resources 包下的 images 包存放着一些项目中使用到的图片。
B/S 端架构
图 9 B/S 项目目录结构
项目主要由 demo 目录下的代码和 resources 目录下的资源组成的。demo 包下的 aspect 包是项目的切面层,主要负责项目日志记录的功能;demo 包下的 config 包是项目的配置层,主要存放着项目中的一些配置类;demo 包下的 controller 包是项目的控制器层,主要存放着项目中的一些控制器类,这些控制器负责向接收和向前端发送请求;demo 包下的 dao 包存放着一些负责数据库操作的接口;demo 包下的 entity 包存放着一些与数据库表产生映射的实体类;demo 包下的 service 包存放着一些实现具体业务逻辑的类和接口。resources 包下面的 static 包存放着一些 HTML 的样式、图片等;resources 包下面的 templates 包下面存放着所有的 HTML 页面。
图 10 数据库表关系图
表 3 s_admin 表
列名 | 数据类型 | 可否为空 | 说明 |
---|---|---|---|
id | int | 否 | 主键 |
name | varchar | 否 | 用户名 |
password | varchar | 否 | 密码 |
createDate | datetime | 否 | 用户创建日期 |
表 4 s_attendance 表
列名 | 数据类型 | 可否为空 | 说明 |
---|---|---|---|
id | int | 否 | 主键 |
student_id | int | 否 | 学生表的 id |
course_id | int | 否 | 课程表的 id |
attendance_date | datetime | 否 | 该选课记录的创建日期 |
表 5 s_class 表
列名 | 数据类型 | 可否为空 | 说明 |
---|---|---|---|
id | int | 否 | 主键 |
name | varchar | 否 | 班级名称 |
info | varchar | 否 | 班级简介 |
表 6 s_course 表
列名 | 数据类型 | 可否为空 | 说明 |
---|---|---|---|
id | int | 否 | 主键 |
name | varchar | 否 | 课程名称 |
teacher_id | int | 否 | 教师表的 id |
max_student_num | int | 否 | 最大学生人数 |
info | varchar | 否 | 课程简介 |
selected_num | int | 否 | 选课人数 |
表 7 s_score 表
列名 | 数据类型 | 可否为空 | 说明 |
---|---|---|---|
id | int | 否 | 主键 |
student_id | int | 否 | 学生表的 id |
cource_id | int | 否 | 课程表的 id |
score | int | 否 | 成绩 |
表 8 s_selected_course 表
列名 | 数据类型 | 可否为空 | 说明 |
---|---|---|---|
id | int | 否 | 主键 |
student_id | int | 否 | 学生表的 id |
course_id | int | 否 | 课程表的 id |
表 9 s_student 表
列名 | 数据类型 | 可否为空 | 说明 |
---|---|---|---|
id | int | 否 | 主键 |
name | varchar | 否 | 学生姓名 |
classId | varchar | 否 | 班级表的 id |
password | varchar | 否 | 密码 |
sex | varchar | 否 | 性别 |
表 10 s_students 表
列名 | 数据类型 | 可否为空 | 说明 |
---|---|---|---|
id | int | 否 | 主键 |
className | varchar | 否 | 班级名称 |
name | varchar | 否 | 学生姓名 |
password | varchar | 否 | 密码 |
sex | varchar | 否 | 性别 |
表 11 s_teacher 表
列名 | 数据类型 | 可否为空 | 说明 |
---|---|---|---|
id | int | 否 | 主键 |
name | varchar | 否 | 教师名称 |
sex | varchar | 否 | 性别 |
title | varchar | 否 | 职称 |
age | int | 否 | 年龄 |
password | varchar | 否 | 密码 |
开发工具:
IDE:IntelliJ IDEA 2020.3
Maven 版本:apache-maven-3.6.3
开发环境:
Windows10 1909 64 位
图 11 系统功能结构图
图 12 C/S 端用户登录
图 13 B/S 端用户登录
功能说明:登录模块主要负责用户登录
特点:
用户在登录时可以选择不同权限的用户登录;
B/S 端的用户登录还带有验证码验证的功能。
图 14 修改密码(C/S 端)
图 16 学生添加(C/S 端)
图 17 学生添加(B/S 端)
图 18 学生列表(C/S 端)
图 19 学生列表(B/S 端)
功能说明:学生管理模块的功能主要有学生添加和学生列表。学生添加可以添加新的学生到系统里面;学生列表则是将全部学生信息用列表显示,同时也可以对每个学生进行删除或修改的操作,还可以按照学生的姓名来进行查找。
图 20 添加教师
图 21 教师列表
功能说明:教师管理模块的功能主要有教师添加和教师列表。教师添加可以添加新的教师到系统中去,新添加的教师也有着相应的权限,可以登录系统进行操作;教师列表则是将所有的教师用列表的形式显示,可以对列表中的教师进行相应的删除和修改操作,也可以对教师进行查询。
图 22 学生签到
图 23 签到管理
图 24 签到统计
功能说明:考勤签到模块的功能主要有学生签到、签到管理和签到统计三个。学生签到主要是学生对未签到的课程进行签到;签到管理则是管理员或教师对学生签到状态的查看和修改;签到统计则是管理员或教师对签到人数的统计。
特点:
该模块的签到统计使用了一个 Java 的可视化包来实现数据的可视化,用户可以选择使用柱状图或饼状图来显示,使人能更直观的看到签到的人数信息。
图 25 成绩录入
图 26 成绩查看
图 27 成绩列表
图 28 成绩统计(C/S 端)
图 29 成绩统计(B/S 端)
功能说明:成绩管理模块主要功能包括成绩录入、成绩查看、成绩列表和成绩统计这四个功能。成绩录入主要是管理员或教师添加各科的学生的成绩;成绩查看是学生查看自己的各科的成绩;成绩列表则是将所有学生的成绩用列表的形式显示出来,管理员和教师可以对其进行修改或删除操作;成绩统计则是将成绩用柱状图或者饼图的形式展示出来。
特点:
B/S 页面使用了 ECharts 进行数据可视化
C/S 端使用了 JFreeChart 进行数据可视化
图 30 选课管理
功能说明:选课管理模块主要是一个选课管理功能。选课管理功能能够对学生的选课进行修改或者退选。
图 31 班级添加(C/S 端)
图 32 班级添加(B/S 端)
图 33 班级列表(C/S 端)
图 34 班级列表(B/S 端)
功能说明:班级管理模块有班级添加和班级列表这两个功能。班级添加可以往系统里面添加新的班级;班级列表则是将所有班级以列表的形式展示出来,可以对展示出来的班级进行删除或修改操作,还可以对班级名称进行搜索。
Windows10
测试内容:
测试方法:
测试内容:
修改密码功能
退出登录功能
测试方法:
测试内容:
添加学生功能
学生列表功能
测试方法:
在添加学生界面输入测试内容
在学生列表界面依次测试删除、修改、搜索功能
测试内容:
测试方法:
在添加教师界面输入测试内容
在教师列表界面依次测试删除、修改、搜索功能
测试内容:
测试方法:
测试内容:
成绩统计
测试方法:
进入成绩录入界面,选择不同的学生和科目,输入成绩
进入成绩统计界面,选择科目进行查询,点击柱状图和饼图,查看显示的内容
测试内容:
测试方法:
在选课管理界面依次测试删除、修改、搜索功能
测试内容:
测试方法:
在添加班级界面输入测试内容;
在班级列表界面依次测试删除、修改、搜索功能。
测试环境:windows10
测试步骤:
进入登录界面,输入用户名、密码和验证码
点击登录
输入数据:
表 11 等价类划分
输入条件 | 有效等价类 | 无效等价类 |
---|---|---|
用户名、密码和验证码的组成 | 用户名的组成为汉字(1);用户名的组成为英文(2);用户名的组成为数字(3);密码的组成为数字(4);密码的组成为英文(5);密码的组成为英文 + 数字(6);验证码的组成为英文 + 数字(7) | 用户名为空(8);密码为空(9);验证码为空(10);用户名和密码输入错误(11);验证码输入错误(12) |
输出数据:无
表 12 测试记录
测试时间 | 测试人员 | 测试结果 | 测试结论 |
---|---|---|---|
6 月 7 日 | Xxx | 正常 | 登陆功能的非空性判断正常 |
6 月 8 日 | Xxx | 正常 | 登陆功能的用户名密码校检正常 |
6 月 9 日 | Xxx | 正常 | 登陆功能的验证码校检正常 |
测试环境:windows10
测试步骤:
进入修改密码界面,输入旧密码、新密码和再次确认新密码,点击确认
进入退出系统界面,点击是、否或取消
输入数据:
表 13 等价类划分
输入条件 | 有效等价类 | 无效等价类 |
---|---|---|
密码的组成 | 密码为数字(1);密码为英文(2);密码为数字 + 英文(3) | 旧密码为空(4);新密码为空(5);旧密码错误(6);两次输入的新密码不相同(7) |
输出数据:无
表 14 测试记录
测试时间 | 测试人员 | 测试结果 | 测试结论 |
---|---|---|---|
6 月 7 日 | Xxx | 正常 | 修改密码功能的非空性判断正常,退出系统功能的各个选项执行功能正常 |
6 月 8 日 | Xxx | 正常 | 修改密码功能的旧密码正确性判断正常 |
6 月 9 日 | Xxx | 正常 | 两次输入的新密码是否相同判断正常 |
测试环境:windows10
测试步骤:
进入学生添加界面,输入学生姓名,选择列表中的班级,输入登录密码,选择学生性别,点击确认或重置;
进入学生列表界面,查看学生信息是否呈列表显示,输入学生姓名,点击查询;点击修改按钮,修改学生信息,点击确认修改;点击学生删除按钮,查看是否将学生删除
输入数据:
表 15 等价类划分
输入条件 | 有效等价类 | 无效等价类 |
---|---|---|
学生姓名的组成、;密码的组成 | 学生姓名为汉字(1);学生姓名为英文(2);密码为数字(3);密码为英文(4);密码为数字 + 英文(5) | 学生姓名为空(6);学生重复添加(7);密码为空(8) |
输出数据:无
表 16 测试记录
测试时间 | 测试人员 | 测试结果 | 测试结论 |
---|---|---|---|
6 月 7 日 | Xxx | 正常 | 学生姓名和密码的非空性判断正常 |
6 月 8 日 | Xxx | 正常 | 学生是否重复添加的判断正常 |
测试环境:windows10
测试步骤:
进入教师添加界面,输入教师姓名,选择教师性别,输入教师职称,输入教师年龄,输入登录密码,点击确认或重置;
进入教师列表界面,查看教师信息是否呈列表显示,输入教师姓名,点击查询;点击修改按钮,修改教师信息,点击确认修改;点击删除信息按钮,查看是否将教师删除
输入数据:
表 17 等价类划分
输入条件 | 有效等价类 | 无效等价类 |
---|---|---|
姓名的组成、;密码的组成、;年龄的组成 | 姓名为汉字(1);姓名为英文(2);密码为数字(3);密码为英文(4);密码为数字 + 英文(5);年龄为数字(6) | 姓名为空(7);重复添加(8);密码为空(9);年龄为空(10);年龄大于 100(11);年龄非数字(12) |
输出数据:无
表 18 测试记录
测试时间 | 测试人员 | 测试结果 | 测试结论 |
---|---|---|---|
6 月 7 日 | Xxx | 正常 | 姓名和密码的非空性判断正常 |
6 月 8 日 | Xxx | 正常 | 教师是否重复添加的判断正常 |
6 月 9 日 | Xxx | 异常 | 教师年龄大于 100 岁的报错 |
测试环境:windows10
测试步骤:
测试时间 | 测试人员 | 测试结果 | 测试结论 |
---|---|---|---|
6 月 7 日 | Xxx | 异常 | 学生签到功能正常,签到统计界面的图表显示正常,但发布签到时能选择已过的日期 |
测试环境:windows10
测试步骤:
进入录入成绩界面,选择学生姓名,选择课程,输入成绩,点击录入成绩;
进入成绩统计界面,选择课程,点击查询;点击切换显示方式。
输入数据:
表 20 等价类划分
输入条件 | 有效等价类 | 无效等价类 |
---|---|---|
成绩的组成 | 成绩为数字(1) | 成绩为空(2);成绩大于 100(3);成绩非数字(4) |
输出数据:无
表 21 测试记录
测试时间 | 测试人员 | 测试结果 | 测试结论 |
---|---|---|---|
6 月 7 日 | Xxx | 正常 | 录入成绩的非空性判断正常 |
6 月 8 日 | Xxx | 正常 | 成绩类型判断正常 |
6 月 9 日 | Xxx | 异常 | 成绩大小范围判断异常 |
测试环境:windows10
测试步骤:
进入班级添加界面,输入班级名称,输入班级简介,点击确认或重置;
进入班级列表界面,查看班级信息是否呈列表显示,输入班级名称,点击查询;点击修改按钮,修改班级信息,点击确认修改;点击班级删除按钮,查看是否将班级删除
输入数据:
表 22 等价类划分
输入条件 | 有效等价类 | 无效等价类 |
---|---|---|
班级名称的组成、;班级简介的组成 | 班级名称为汉字(1);班级名称为英文(2);班级名称为数字(3);班级名称为汉字 + 数字(4);班级简介为任意输入(5) | 班级名称不为空(6);班级简介不为空(7) |
输出数据:无
表 23 测试记录
测试时间 | 测试人员 | 测试结果 | 测试结论 |
---|---|---|---|
6 月 7 日 | Xxx | 正常 | 班级名称和简介的非空性判断正常 |
表 24 测试统计
编号 | 测试项 | 执行测试总次数 | 发现的错误数 |
---|---|---|---|
1 | 用户登录 | 10 | 0 |
2 | 系统设置(包含修改密码、退出登录) | 10 | 0 |
3 | 学生管理(包含学生添加、学生列表) | 20 | 0 |
4 | 考勤签到(包含学生签到、签到管理、签到统计) | 20 | 1 |
5 | 教师管理(包含教师添加、教师列表) | 20 | 1 |
6 | 成绩管理(包含成绩录入、成绩统计) | 20 | 1 |
7 | 班级管理(包含班级添加、班级列表) | 20 | 0 |
表 25 缺陷分析
编号 | 测试项 | 错误类型 | 错误数量 | 解决方法 |
---|---|---|---|---|
1 | 考勤签到模块中的签到管理功能 | 日期范围错误 | 1 | 设置判断将今天之前的日期列为禁选状态 |
2 | 教师管理模块中的教师添加功能 | 年龄范围错误 | 1; | 重新设置年龄判断,将小于 120 岁的输入设置为合法范围 |
3 | 成绩管理模块中的成绩录入功能 | 成绩范围错误 | 1 | 重新设置年龄判断,将 150 分设置为分数上限 |
最终结论:
本次测试验证过程中共发现了 3 个错误,全部都是一些数字或日期的范围错误,证明我们在代码编写过程中一些功能点的设计考虑不足,才出现这些细小的错误;
本次测试验证过程中没有进行性能测试,故没能反映出程序的性能优劣;
团队活动记录 1:
团队活动记录 2:
团队活动记录 3:
明确答辩 ppt 和答辩文档的编写任务。
分配测试任务,对 Web 端已实现的功能进行集中测试。
图 35 团队活动(a)
图 36 团队活动(b)
图 37 团队活动(c)
职责:在本组中的职位为组长,负责监督组员每天的开发进度,解决组员一些开发上面遇到的问题,统筹分配每个阶段组员的开发任务,定期总结具体开发中的不足和解决方法。
开发任务:负责所有模块的后端代码的编写、整体开发框架的构建、前端代码的修改,外加给组员解决开发中遇到的问题。
成果:
开发了 C/S 端的系统设置模块、学生管理模块、教师管理模块、考勤签到模块、成绩管理模块、选课管理模块、班级管理模块;B/S 端的系统设置模块、班级管理模块和成绩管理模块的部分功能。
负责答辩 ppt 和课设总结报告的部分内容编写。
总结整理了关于开发过程中遇到的问题成文档的形式。
在普通 JavaSwing 项目中整合使用 Spring 和 MyBatis
这是 C/S 端的核心技术,同时也是 C/S 端的创新点之一,整合使用了 Spring 和 MyBatis,这样做的优点有三个。第一个是方便分层,传统 C/S 项目一般都之分 Dao 层和 View 层,对于具体业务的逻辑都放到 Dao 层里面了,这使得 Dao 层里面的业务逻辑跟 JDBC 的数据库操作混在一起,项目较为臃肿;第二个是使用 Spring 里面的 DI(依赖注入)和 IoC(控制反转)思想,可以将对象交给容器管理,由容器来掌握对象的创建和使用,降低了程序的耦合度,使得项目的臃肿度下降;第三个是 MyBatis 封装了 Java 的 JDBC 的部分操作,使我们只用专注于 SQL 语句本身,而不用更多地专注于代码的实现,极大地减少了数据库操作的代码量,而 MyBatis 和 Spring 整合之后可以在接口上直接使用注解来完成 Dao 层的绝大部分操作。
事件派发线程(EDT,Event Dispatcher Thread),顾名思义是用来派发事件(根据事件找到对应的事件处理代码)的线程。EDT 接收来自 toolkit 线程的事件,并且将这些事件组织成一个队列,EDT 的工作内容就是将这个队列中的事件按照顺序派发给相应的事件监听器,并且调用事件监听器中的回调函数,这也意味着,所有的事件处理代码都是在 EDT 而不是主线程中执行。
一个是程序启动时就产生的线程,执行 main()方法,一个是 JavaSwing 的事件派发线程(EDT),所以只要使用 JavaSwing 就设计到多线程操作。
而 Spring 框架中的 Bean,或者说组件,获取实例的时候都是默认单例模式,单例模式的意思是只有一个实例,例如在 Spring 容器中某一个类只有一个实例,而且自行实例化后并项整个系统提供这个实例。也就是说在多线程环境下 Spring 进行依赖注入的方式得做出改变,如下:
Spring 在多线程中的依赖注入解决方案:
主要有四种,分为两种思路:
JFreeChart 是一个免费的 Java 图表库。它完全使用 Java 语言编写。可生成饼图(pie charts)、柱状图(bar charts)等多种图表在项目中负责数据可视化的部分操作。
在 Web 端使用 SpringBoot 和 Spring Data JPA
Web 端使用的技术栈是 SpringBoot+Spring Data JPA。Spring Boot 是用来简化 Spring 的搭建和开发过程的全新框架。Spring Boot 去除了大量的 XML 配置文件,简化了复杂的依赖管理,配合各种 starter 使用,基本上可以做到自动化配置。Spring 可以做的事情,现在用 Spring boot 都可以做。
在介绍 Spring Data JPA 之前先介绍一下 Hibernate。Hibernate 是数据访问解决技术的绝对霸主,使用 O/R 映射(对象关系映射)技术实现数据访问,O/R 映射即将领域模型类和数据库的表进行映射,程序通过操作对象而实现表数据操作的能力,让数据访问操作无须关注数据库相关技术。随着 Hibernate 的盛行,Hibernate 主导了 EJB(EnterpriseJavaBean)3.0 的 JPA(JavePersistenceAPI)规范。JPA 是一个基于 O/R 映射的标准规范。所谓规范即只定义了标准规则(如注解、接口),不提供实现,软件提供商可以按照标准规范来实现,而使用者只需按照规范中定义的方式来使用,而不和软件提供商的实现打交道。JPA 的主要实现有 Hibernate、EclipseLink 和 OpenJPA 等,这也意味着我们只要使用 JPA 来开发,无论是哪一个开发方式都是一样的。SpringDataJPA 是 SpringData 的一个子项目,它通过提供基于 JPA 的 Repsitory 极大地减少了 JPA 作为数据访问方案的代码量。
我们使用 SpringBoot 框架简化了原先 SpringMVC 繁杂的配置,将原本 JavaWeb 框架中需要配置的 Tomcat、数据库等各种配置项都帮我们自动化配置好了。Spring Data JPA 因为它内部封装了一些常用的数据库的操作,如:增删改查等,则帮我们省略了绝大部分的简单 SQL 语句的编写操作,使我们的关注点转移到业务的优化与实现上。
在 Web 端使用 Spring Data JPA 对数据库中获取到的数据进行分页
分页的必要性:如果一次性加载成千上万的列表数据,在网页上显示将十分的耗时,用户体验不好。所以处理较大数据查询结果展现的时候,分页查询是必不可少的。分页查询必然伴随着一定的排序规则,否则分页数据的状态很难控制,导致用户可能在不同的页看到同一条数据。
所以使用 Spring Data JPA 对数据进行分页就很有必要,这里使用 Pageable 这个接口,Pageable 是 Spring 定义的接口,用于分页参数的传递。首先将 ArticleRepository 注入到你需要进行持久层操作的类里面,通常是一个@Service 注解的类,然后在服务方法内使用如下代码进行分页操作:显示的页码,查询 pageSize 条数据,使用 JPA 提供的 Sort 对象,按照 Sort 方式排序(Sort 是 JPA 提供的一个排序机制)
图 38 分页的实现
findAll 方法以 Page 类的对象作为响应,如果我们想获取查询结果 List,可以使用 getContent()方法。但是笔者不建议这样进行转换,因为前端展示一个分页列表,不仅需要数据,而且还需要一些分页信息。如:当前第几页,每页多少条,总共多少页,总共多少条。这些信息在 Page(articlePage)对象里面均可以获取到。
在 Web 端使用 Thymeleaf 模板引擎代替 AJAX 完成前后端交互
Thymeleaf是一个流行的模板引擎,该模板引擎采用Java语言开发,模板引擎是一个技术名词,是跨领域跨平台的概念,在Java语言体系下有模板引擎,在C#、PHP语言体系下也有模板引擎。除了thymeleaf之外还有Velocity、FreeMarker等模板引擎,功能类似。Thymeleaf的主要目标在于提供一种可被浏览器正确显示的、格式良好的模板创建方式,因此也可以用作静态建模。你可以使用它创建经过验证的XML与HTML模板。使用thymeleaf创建的html模板可以在浏览器里面直接打开(展示静态数据),这有利于前后端分离。需要注意的是thymeleaf不是spring旗下的。在课设中我们使用Thymeleaf主要是为了加快课设进度,因为Thymeleaf规范写的html页面不需要使用ajax进行前后端交互,所以可以减少前后端交互花费的时间。
使用 Spring 的 AOP 在 Web 端配置日志切面,使得每个操作都能记录在日志中
什么是 AOP:AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP 是 OOP(面向对象编程)的延续,是软件开发中的一个热点,也是 Spring 框架中的一个重要内容,是函数式编程的一种衍生范型。利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。我们在这里使用切面编程,无侵入式的配置日志切面,将我们的每个操作都记录下来,形成我们的日志。
配置拦截器,使得用户在未登录之前无法通过 URL 访问其他页面
概念:Java 里的拦截器是动态拦截 Action 调用的对象,它提供了一种机制可以使开发者在一个 Action 执行的前后执行一段代码,也可以在一个 Action 执行前阻止其执行,同时也提供了一种可以提取 Action 中可重用部分代码的方式。
JPA 的修改删除操作不同于 MyBatis,它有着一些限制,默认情况下, JPA 的每个方法上有事务, 但都是一个只读事务。 他们不能完成修改操作。所以需要使用删除和修改操作时必须得加上事务操作。
使用 Spring 进行依赖注入遇到的问题
Swing 是 Java 的一个进行 GUI 开发的包,在课设中我们使用 Spring 对容器进行管理,但是在使用 Spring 注解进行容器依赖注入的时候出现了一个问题,依赖注入为 null,报错如下:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.view.LoginFrm.loginAct(LoginFrm.java:187)
at com.view.LoginFrm$2.actionPerformed(LoginFrm.java:96)
在百度找了许久没找到问题所在,排除了 Spring 配置文件写错、或者是没加@Service 注解等问题之后,我找到了网上的一个解释,如下:
而 Spring 在多线程的情况下是不允许使用注解注入依赖的,所以我们只能手动 get 到我们想要的 bean 对象,代码如下:
private final ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
private final AdminService adminService = (AdminServiceImpl)context.getBean("AdminServiceImpl");
附 Spring 在多线程中的依赖注入解决方案:
主要有四种,分为两种思路:
在编写查找指定签到方法的时候,我使用了 List
@Results({
@Result(property = "key",column = "attendance_num",jdbcType = JdbcType.INTEGER),
@Result(property = "value",column = "attendance_date",jdbcType = JdbcType.VARCHAR)})
但是它显示格式转换错误,于是我在控制台输出了一下查询结果,发现结果是这样的
[ {value=2018-05-17, key=1}, {value=2018-04-17, key=1}, {value=2018-04-18, key=1}, {value=2018-04-19, key=3}, {value=2018-04-20, key=1}, {value=2018-04-21, key=1}, {value=2018-05-03, key=1}]
HashMap 里面的值从 JSON 字符串的形式变成了 xxx=xxx 的形式,property 属性值对应的是实体类的属性,但是 HashMap 里面的 key 和 vlaue 并不能算属性(是我想错了),所以此时 MyBatis 就会自己设置一个属性名,于是就变成了上面的结果。别问为啥不用 XML 文件的形式,问就是太懒了,不想再写 XML 文件。
处理:
将上面的结果值重新处理一下,再赋给 HashMap
删除带外键关联的数据时出现的问题总结
今天项目中 Service 层报错,如下:
Cannot delete or update a parent row:a foreign key constraint fails (`ttms`.`s_attendance`, CONSTRAINT `student_attendance_foreign` FOREIGN KEY (`student_id`) REFERENCES `s_student` (`id`));nested exception is java.sql.SQLIntegrityConstraintViolationException:Cannot delete or update a parent row:a foreign key constraint fails (`ttms`.`s_attendance`, CONSTRAINT `student_attendance_foreign` FOREIGN KEY (`student_id`) REFERENCES `s_student` (`id`))
查看了一下错误信息,问题出在 Dao 层,一条删除语句出现问题了,分析了一下原因,发现是设置了外键关联,这导致我们无法删除该条数据。
解决方法:
在删除数据前先设置外键无效,如下:
set foreign_key_checks = 0;
然后此时可以执行删除语句了
删除完之后再设置外键有效,如下:
set foreign_key_checks = 1;
这样就完美地删除了这条记录了。
使用 JPA 更新数据库时遇到的问题
今天使用 JPA 做 Web 端的持久化层的内容时,遇到了一个错误,如下:
Executing an update/delete query
在百度查找一番之后,发现是 JPA 如果执行 update 或 delete 等操作时,要在 Dao 或者 Service 层加上@Transactional 注解,代表这是一个事务级别的操作,这相当于 JPA 的一个使用规范吧,因为 JPA 要求,’没有事务支持,不能执行更新和删除操作’。
window.onload = function()函数不执行的问题
图片 39 问题 5(a)
上图中的函数应该在页面加载完之后就立刻执行,但实际上并没有执行,这导致页面显示为空,寻找了许久问题的出处,最终定位到下图处
图片 40 问题 5(b)
总结:
window.onload 出现在 body onload 属性的后面的情况.等加载完 body 的页面,再执行 onload 事件,后面 onload 事件是可以覆盖前面的 body onload 属性.
Js 的字符串传参问题
在写下面这条语句时字符串参数总是传递失败
原因:
使用 AJAX 获取数据要在前端拼接字符串。我直接就将变量传过去了,结果导致传的参数一直是未定义的。
通过查询得知需要加转义字符
如下:
如果是单引号内:
οnclick='functionName(\"" + StringName + "\")'
如果是双引号内:
οnclick="functionName(\''+StringName+'\')"
代码改正后:
课设开始阶段,因为对课程设计所要做的东西不是很清楚,大家都处在摸石头过河阶段,因为主要的技术方面还没有掌握,所以大家决定先做后台管理系统,因为这部分在老师给的框架里面已经有了成功的例子可以仿照学习,有了方向,组长给我们每个人分配了任务,我一开始负责做后台功能的实现,一开始也就模仿老师给的框架里的方法来做,但是后来出现了前所未有的问题,我或者其他组员都会第一时间放下手头的工作和我一起来解决问题,在其他人出现问题的时候我们也是这样做的,这样我们问题解决的速度就快了不少,但是因为我们知识匮乏有些问题实在没有办法组内解决,我们就会去找班里在这方面学的比较好的同学,老师也会耐心的在前面等待同学提问题,遇到了实在解决的问题我们就会去找老师,做了两天之后我们发现后台管理里的学生管理和学生添加完全可以放在一起,因为学生添加内容较少且学生管理包含了部分学生添加的内容,最后我们组内商量决定将学生添加合并到学生管理里面。
陆陆续续我们也做完了初期手头的工作,对课设要做什么,要了解什么都有了一定的认识,那么我们开始规划下一阶段的任务,经过几天的实践,几位同学比较适合前端,几位同学比较适合做后端,我通过这些特点给我们分配了合适的任务,而我则去做了所有的前后端,前端相对简单,所以我把重心放在了后端的交互上,在功能实现上遇到了很多问题,这中间我请教了很多已经实现的同学,也问了老师,组员也给我了很多帮助,让我学到了很多东西。
课设的过程其实也是枯燥的,很多重复的代码编写,很多小错误的修正,很多知识盲点要补充,但是我们都没有气馁,在课设期间我们也会互相开一些小玩笑调节一下严肃的气氛,有时候在加班时间会在群里发一些表情包,八卦八卦,在路上看到了好看的风景拍下来发到群里,正因为有了这些才让我能够坚持下来。
经过两周多的时间,我们小组还算交了一份不错的答卷,这是我们每个人的努力结果也是我们小组互相帮助、互相勉励的结果,我们每个人都从中学到了很多。
教训:
收获:
课设让我对今后的发展方向有了进一步的认识,这次课设用到的前端、后端、数据库的知识很多,通过两周的实践让我发现我更加喜欢后台一些,我也希望更深层次的去了解后端知识,学习后端,当然学习前端知识也同样重要,毕竟只有包罗万象才能胸有成竹,在还没有决定发展方向之前我选择前端和后端都做研究,在更深层次的接触和时间之后再决定以后的方向。
总而言之,这次课程设计让我收获颇丰,感触良多,不仅学习了 ECharts、JFreeChart 等等很多新知识,了解了如何去做一个项目,同时也认识到了自己身上很多的不足等着我去改正,我相信以后再去解决类似的问题,我会更加得心应手,我也会在以后的日子里不断修炼强大自己,让以后的路更宽敞更好走!
开发任务:
在本次学生信息管理系统的项目开发中,我主要担任了前期数据库的设计,及其 SQL 代码的编写部分;以及后期学生信息管理系统的部分功能的测试。
开发成果:
用 MySQL 实现数据库的管理:
数据库系统:
数据库系统是由数据库、数据库管理系统(及其应用开发工具)、应用程序和数据库管理员组成的、管理、处理和维护数据的系统。
其中数据库是长期存储在计算机内、有组织、可共享的大量数据的集合。数据库中的数据按一定的数据模型组织、描述和储存,具有较小的冗余度、较高的数据独立性和易扩展性,并可为各种用户共享。与工作量大、编程复杂、且开发速度满的文件存储模式相比大大的提高了程序员的开发效率,也方便了我们这次学生信息管理系统在 C/S 端和 B/S 实现数据的共享。
数据库管理系统:
数据库管理系统是位于用户与操作系统制间的一层数据管理软件。本次实验所编写学生信息管理系统使用的 MySQL 便是数据库管理系统。
MySQL:
关系数据库:
关系数据库是以数据模型来分类的,而主要的逻辑数据模型有:层次模型、网状模型、关系模型、关系模型、面向对象模型、对象关系数据模型、半结构化模型,其中的关系模型的数据结构十分简单,只包含单一的数据结构――关系。在用户看来,关系模型中的数据的逻辑结构就是一张扁平的二维表。
关系模型与网状模型和层次模型不同,他是建立在严格的数学概念的基础上的。他的概念模型单一,无论实体还是实体之间的练习都用关系来表示,使其数据结构简单、清晰,用户易懂易用。关系模型的存取路径对用户透明,从而具有跟高的数据独立性、更好的安全保密性,也简化了程序员的工作和数据库开发建立的工作。但因为其存取路径对用户是隐蔽的,查询效率往往不如层次模型和网状模型,因此为了提高性能关系模型的数据库管理系统必须对用户的查询请求进行优化,增加了开发数据库管理系统的难度。
SQL:
SQL 是关系数据库的标准语言但目前没有一个数据库系统能够支持 SQL 标准的所有概念和特性。我们在学生信息管理系统中所用的 MySQL 就是采用的 SQL 标准,它对 SQL 的基本命令级进行了不同程度的扩充和修改,并支持标准外的一些功能特性。
SQL 的特点:
1.综合统一。SQL 集数据定义语言、数据操作语言、数据控制语言的功能于一体,语言风格统一,可以独立完成数据库生命周期中的全部活动,包括:定义和修改、删除关系模式,定义和删除视图,插入数据,建立数据库;对数据库中的数据进行插叙和更新;数据库重构和维护。数据库安全性、完整性控制,以及事务控制。嵌入式 SQL 和动态 SQL 定义。
2.高度非过程化。在用 SQL 语言进行数据操作是,只要提出“做什么”,而无须指明“怎么做”。因此无须了解存取路径。存取路径的选择以及 SQL 的操作过程由系统自动完成。
3.面向集合的操作方式。SQL 采用集合操作方式,不仅操作对象、查询结果可以是元组的集合,而且一次插入、删除、更新操作的对象也可以是元组的集合。
4.以同一种语法结构提供多种使用方式。SQL 既是独立的语言,又是嵌入式语言。作为独立的语言,它能独立地用于联机交互的使用方式,用户可以在终端键盘上直接键入 SQL 命令对数据库进行操作;作为嵌入式语言,SQL 语言能够嵌入到高级语言(如:本次学生信息管理系统所使用的 Java 语言)程序中,供程序员使用。而在这两种不同的使用方式下,SQL 的语法结构基本上是一致的。
5.语言简洁,易学易懂。SQL 语言功能极强,但设计巧妙,语言十分简洁,核心功能只用了 9 个动词(SELECT,CREATE,DROP,ALTER,INSERT,UPDATE,DELETE,GRANT,REVOKE)。
E-R 模型:
E-R 模型也称实体-联系方法或 E-R 方法,它是用来描述现实世界的概念模型。包括实体、属性、实体之间的联系。
其中实体之间的联系分为:
JDBC:
JDBC 是一种用于执行 SQL 语句的 Java API,可以为多种关系数据库提供统一访问,它由一组用 Java 语言编写的类和接口组成。 JDBC 提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
JDBCAPI 是处于链接应用程序和数据库的位置,但是因为对于不同的数据库管理系统中其就算是都以 SQL 语言为标准,它们也有自己的属于标准外的一些功能特性。因此这些各个数据库厂商对自己的数据库链接驱动,以完成他们对 JDBCAPI 的一些实现。本次学生信息管理系统就使用的 MySQL Driver。
数据库的链接步骤:
DAO 设计模式:
DAO 的全称是 data access object ,其中非常重要的一个概念是 Domain 对象,也就是说一个最常用的 POJO 对应数据库中的一个表与之对应,实际项目中,我们经常会通过查询获取数据,然后将数据用于其他的用途,并非简单的打印或者展示,其次,在实际的应用中,和数据库打交道的 JDBC 代码会很少出现在业务逻辑之中,因为这样对代码的维护以及再扩展会带来极大的开销,所以会尽量的将数据层的东西抽取出来,让代码显得干净一些,这也就是 DAO 模式最需要解决的问题之一,当然 DAO 模式最大的好处是通过数据访问层的接口完全隐藏了数据层的实现细节,让业务层不需要关心具体的细节。
MyBatis:
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
配置开发环境时的问题
这个问题其实并不是在正式做课设时出现的,而是在这之前为课设做准备时出现的问题,而且那时是在 Eclipse 上搭建的 TTMS,而不是我们课设时做的学生信息管理系统,但通过这次的错误我也初步了解了开发一个 B/S 架构的软件所需要的知识和大致框架。
这次问题出现在配置 Tomcat 和 Servelet 上,再导入老师的项目模板过后,出现了 Servlet 中缺少包的问题,而根据老师的步骤进入 Build Path 后在 Add Library 界面并未出现 Server Runtime 的选项,再通过百度后,查找问题按照其中的步骤终于出现了 Server Runtime 的选项,在添加完成后项目名前不在出现红叉,然而运行的时候却依然报错,开始时只是不断地尝试百度上的各种方法,但未能有效,最后在之前下载 Tomcat 的目录下出现了一个新的 Tomcat,通过查询发现在之前解决 Server Runtime 的问题时并没有采用我自己的 Tomcat,而是自己下载了一个新的,而且因为某种原因并未下载成功,只是创建了以个同名的目录,而 Eclipse 把这个目录给识别了,导致了项目名前并未出现红叉,而运行时却报错的现象,最后把他改成了自己已下载好的 Tomcat,总算成功,不过因为之前不小心建了一个 Tomcat,加上自己的不注意导致重名,因此在选择 Tomcat 时最后面还有各个“(1)”的后缀。不过因为在课设正式开始时我们并未选择使用这个 TTMS,而是在 idea 上编写学生信息管理系统,所以最后并未修改这个问题。
数据库设计时的问题
在进行数据库设计时因为我并没有按照数据库设计的流程来进行,只是按照之前讨论的需要做的功能,一边想每个功能中需要什么样的数据,然后就直接开始建表,编写 SQL 代码了,可是在写了一部分过后,因为例如学生与课程、老师与课程、老师与班级、学生与班级他们之间的各种关系,和一些互通的数据,让我编写到后面时十分混乱,从而浪费了许多的时间。
后来开始先建立好概念模型,画好 E-R 图,在理解好各个数据之间的关系和互通点之后再开始把它们转换成 SQL 代码。这样效率提高的同时,也让我对其流程更加清楚。
在这之后,我们进行了第一次的整合,但是当设计好过后,我们准备再这次的基础上添加成绩模块时,又出现的一些问题,我发现添加一个新功能时,修改数据的时候要改很多部分。
因此我又将之前的都写再一个 SQL 文件里的 SQL 代码给分出来,将他们分成多个表,并分配再不同的 SQL 文件里面(如下图所示)这样不仅清晰了代码而且利于之后添加新功能时,更方便的操作了。
图 42 数据库文件
加载方法无效
在前端写入 onload 方法可以在页面初始化的时候加载 onload 的方法,但是在实际操作的时候发现 onload 方法无效,无法使搭载的函数生效,这就要想想 onload 初始化方法的其他解决方式,下面就是所有初始化的方法。
图 43 三种方法
但是所有方法试过了之后发现还是没有用,之后我在老师给之前发的关于 TTMS 的框架里发现了老师的使用的方法,他是直接在方法体外层加一层括号再在后面加一个括号,让此方法立即执行,通过尝试过后发现非常管用
脚本模型
btn.οnclick=function() {}
下面两种方法效果是一样的
document.getElementById("target").onclick();
document.getElementById("target").click();
备注:
btnObj.click()是真正地用程序去点击按钮,触发了按钮的 onclick()事件
btnObj.onclick()只是简单地调用了 btnObj 的 onclick 所指向的方法,只是调用方法而已,并未直接触发事件
事件写法:
添加事件:appEventListener(事件名,事件函数,false )
btn.addEventListener('click',function() {},false);
btn.addEventListener('click',function() {},false);
移除事件:removeEventListener(事件名,事件函数名,false)
btn.removeEventListener('click',show,false )
在冒泡中,内部元素的事件会先被触发,然后再触发外部元素,即:
元素的点击事件先触发,然后会触发元素的点击事件。
在捕获中,外部元素的事件会先被触发,然后才会触发内部元素的事件,即:
元素的点击事件先触发 ,然后再触发元素的点击事件。
在本次刚开始课程设计时,因为我们组的成员中除组长外并没有项目开发的经验,所以组长分配给我了本学期刚学的数据库部分,他进行代码框架的搭建,其他成员负责前端页面的设计。这种分配方式对于我们刚接触项目开发的人来说比较友好,因为在这个阶段我们所做的部分都还比较独立,只是需要在制作之前的需求分析中商量好需要那些模块。
对于我所负责的数据库设计部分来说,我需要尽快的确定好需要创建好哪些表,及其之间的关系,搭建好概念模型,画好 E-R 图,然后上传至小组群文件中。通过商量确定好概念模型后,就可以开始自己的 SQL 代码的编写了。在完成这部分内容过程中,我通过组长已编写部分学习一下整体的框架,和代码和数据库链接时所需要的知识,以便于完成 SQL 代码的编写后的部分能够尽快进行。
在完成数据库部分过后,或许是因为我的学习效率比较缓慢,所以即使有了一段时间的过度、我还是出现了和其他同学刚开始一样的问题。所幸在我遇到问题时组长都会为我耐心解答,就是在这样的学习状态和组长的帮助下,我们渐渐的完成了各个部分的整合。
为期两周多的课设终于结束了,通过这次课程设计,使我更加扎实的掌握了一些有关方面的知识,在课程设计中虽然遇到了问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了问题所在,也暴露出了前期我在这方面的知识的欠缺与经验不足。实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵。
这次课设刚开始我显得很盲目,好在我们组长有一定的项目经验,并且在给我们分配任务时,先给我分配的是这学期刚学的数据库设计部分,这让我可以很快的直接上手,进行项目的开发,并且学习有时间学习一下之后会用到的一些新技术。当完成这部分以后,慢慢开始接触到一些陌生的事物,就算是给了一定的缓冲时间我还是感觉到无从下手,这块做一点那块做一点,理解的很缓慢,很多东西不了解,很多知识不清楚,不过通过学习加上仿照组长已完成的代码,过了两三天的摸索也还是有所进展。同时我也发现了自身的问题,那就是学习能力不强,没有一个快速掌握知识的方法。面对很多不了解的知识点,我学习的速度和掌握的速度明显有点慢了,也多亏了组长和其他同学的一些协助我才慢慢进步,扩充自己。
我认为,在这学期的实验中,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。更重要的是,在实验课上,我们学会了很多学习的方法。而这是日后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断的学习、实践,再学习、再实践。这对于我们的将来也有很大的帮助。以后,不管有多苦,我想我们都能变苦为乐,找寻有趣的事情,发现其中珍贵的事情。就像中国提倡的艰苦奋斗一样,我们都可以在实验结束之后变的更加成熟,会面对需要面对的事情。
回顾起此课程设计,我感慨颇多,从理论到实践,不仅了解了前后端的项目的开发流程、也了解了像 JDBC、DAO、Spring、MyBatis 等等很多很多新知识,虽然对他们的理解并不是很到位,写出来的东西也大多是照猫画虎,但也明白项目开发的一些流程,也为接下来的暑假时间找到了学习的目标,同时也认识到了自己身上很多的不足等着我去改正,我相信以后再去解决类似的问题,我会更加得心应手,有什么不懂不明白的地方要及时请教或上网查询,只要认真钻研,动脑思考,动手实践,就没有弄不懂的知识,收获颇丰。
在项目组中主要负责前端页面的编写和软件测试功能,负责教师端和部分学生端的界面编写,负责软件测试,在开发功能代码之前,先编写测试代码,然后只编写使测试通过的功能代码,从而以测试来驱动整个开发过程的进行,有助于编写简洁可用和高质量的代码,有很高的灵活性和健壮性,能快速响应变化,并加速开发过程,在代码编写完成后,对所开发的功能进行测试,看开发功能是否完善,逻辑功能是否存在问题。
教师端的功能有学生管理,班级管理,教师管理,课程管理,选课管理 5 个功能,学生管理包括学生列表和学生添加板块,班级管理包括班级列表和班级添加板块,教师管理功能展示教师列表,课程管理包括添加课程和课程列表功能,选课管理对学生所选课程进行管理。编码完成后进行软件项目测试。学生端的功能有学生管理和选课管理,学生管理学生端展示学生列表。
图 45 教师端主要功能界面
图 46 学生端主要功能界面
技术难点:
前端本身业务逻辑、实现方式比较多样、复杂,技术选型、方案设计很难,所以要求我们对多种技术框架、工具都有一定的了解。面对不同业务需求进行抽象、设计、研发以及关联系统的自主研发(跨技术栈)比较难。将业务需求、交互设计、数据等糅合在一起开发出来展现给用户,跟多方沟通打交道比较难,良好的沟通需要多种领域的知识。
前端逻辑复杂度主要在于数据 +UI+ 交互的实现,就比如一个简单的多 tab 页的功能,可以用 CSS 实现,用 JS 实现,JS 可以通过 remove DOM 或者添加 classname 隐藏,虽然效果上都可以实现,remove DOM 无法原有结构的状态,添加 classname 的 CSS 方式很难实现初始化状态。如果需要突然需要改什么效果或者之前开发的不合理,基本上要重做了。
当需求发生变化的时候,首先就直接是前端的改变,所以必须适应需求的变化,即前端开发的难点之一就是让前端开发适应快速变化的需求,以满足用户的不同需求。
其次,平台、浏览器生态复杂,要考虑的场景太多,我们这次课程设计只开发了网页端,但是在实际的前端开发中,为了满足用户不同设备上使用的要求,需要提供多客户端,最起码要有网页端、iOS 端和安卓端,现在大部分产品还要考虑小程序端,安卓也要考虑手机和平板…各种设备、各种版本、各种浏览器都有各自的特点和 bug,很多精力可能都消耗在处理某个特定平台/版本/浏览器的 bug 上,造成了不同平台上实现同一界面功能的重复劳动严重,所以前端难点之二就是消除前端开发的重复劳动。
核心技术:
BootStrap
BootStrap 概述
BootStrap 是一个基于 HTML、CSS、JavaScript 的开源框架。该框架代码简洁、视觉优美,可用于快速、简单地构建基于 PC 及移动端设备的 Web 页面需求。经过很长时间的迭代升级,由最初的 CSS 驱动项目发展成为内置很多 JavaScript 插件和图标的多功能 Web 前端的开源框架。BootStrap 最为重要的部分就是它的响应式布局,通过这种布局可以兼容 PC 端、PAD 以及手机移动端的页面访问。
BootStrap 特点
主要核心功能特点如下:
CSS 目录中有四个 CSS 后缀的文件,其中包含 min 字样的,是压缩版本,一般使用这个;不包含的属于没有压缩的,可以学习了解 CSS 代码的文件;而 map 后缀的文件则是 CSS 源码映射表,在一些特定的浏览器工具中使用。
Jquery
jQuery 简介
jQuery 是一套跨浏览器的 JavaScript 函式库,简化了 HTML 和 JavaScript 之间的操作。jQuery 是开源软件,使用 MIT 许可证授权 jQuery 的语法设计使得许多操作变得容易,如操作文档对象(document)、选择文档对象模型(DOM)元素、创建动画效果、处理事件、以及开发 AJAX 程序。jQuery 也提供了给开发人员在其上创建插件的能力。这使开发人员可以对底层交互与动画、高级效果和高级主题化的组件进行抽象化。模块化的方式使 jQuery 函数库能够创建功能强大的动态网页以及网络应用程序。
jQuery 特点
jQuery 是一款轻量级的 js 框架,jQuery 核心 js 文件才几十 kb,不会影响页面加载速度。与 Extjs 相比要轻便的多。
jQuery 的选择器用起来很方便,好比说我要找到某个 dom 对象的相邻元素 js 可能要写好几行代码,而 jQuery 一行代码就搞定了,再比如我要将一个表格的隔行变色,jQuery 也是一行代码搞定。
jQuery 有着丰富的第三方的插件,例如:树形菜单、日期控件、图片切换插件、弹出窗口等等基本前台页面上的组件都有对应插件,并且用 jQuery 插件做出来的效果很炫,并且可以根据自己需要去改写和封装插件,简单实用。
jQuery 可扩展性强,jQuery 提供了扩展接口:JQuery.extend(object) , 可以在 jQuery 的命名空间上增加新函数。jQuery 的所有插件都是基于这个扩展接口开发的。
Servelet
Servlet 简介
Servelet 是运行在服务器端的程序,可以被认为是服务器端的 applet。Serlvet 被 Web 服务器 Tomcat 加载和执行,就如同 applet 被浏览器加载和执行一样,servlet 从客服端通过 Web 服务器接收请求,执行某种操作,然后返回结果。狭义的 servlet 是指 Java 语言实现的一个接口,广义的 servlet 是指任何实现了这个 servlet 接口的类,一般情况下将 servlet 理解为后者。从原理上讲,servlet 可以响应任何类型的请求,但绝大多数情况下 servlet 只用来扩展基于 HTTP 协议的 Web 服务器。
Serlvet 主要优点:
Servlet 是持久的,Servlet 只需要 Web 服务器加载一次,而且可以在不同请求之间保持服务,如一次数据库连接。
Serlvet 是与平台无关的,servlet 是用 Java 编写的,自然也继承了 Java 的平台无关性。
Servlet 是可扩展的,由于 Servlet 是用 Java 编写的,所以它具备了 Java 所能带来的优点。Java 是健壮的、面向对象的编程语言,它很容易扩展以适应你的需求,servlet 自然也具备了这些特征。
Servlet 是安全的,从外界调用一个 servlet 的唯一方法就是通过 Web 服务器,这提供了高水平的安全性保障,尤其是在你的 Web 服务器有防火墙保护的时候。
Servlet 可以在多种多样的客户机上使用,由于 servlet 是用 Java 编写的,所以可以很方便的在 HTML 中使用他们。
目标不明确
学生信息管理系统开发前准备不够充分,分析不够清楚明了,就比如开发工作进行前,对整个系统所需要达到的目标没有基本的、明确的、全面的的概念,就照着自己的想法做下去,进行设计和开发,做了大量工作后才发现设计不合理,而使得系统有些部分就得重新开发,就比如我们小组,在课程设计刚开始前期,并没有决定要开发桌面端,项目设计进行到一半时,经过老师的提醒,我们在项目开发的后半段时间才开始开发网页端,这就造成了时间分配很不合理,网页开发时间比较紧,一些功能不完善,所以在老师提出我们的问题时,我们组加紧重新合理安排分工,不同用户登录端不同人员进行开发,加紧前端网页的开发,终于合理完成了任务。
在代码编写过程中
项目刚开始进行时,小组成员之间各写各的,缺乏分工合作。对项目开发用到的语言有些部分不是很熟悉,所以这块工作任务不能准确掌握。有些表达比较晦涩难懂。所以在项目进行了一段时间后,组内交流,通过交叉检视,使不同成员之间相互熟悉对方的开发工作,避免缺乏合作。
开发阶段一般是遇到问题做多的时期,首先就是要详细的读完需求分析,要明确自己接下来的工作具体要做什么,然后制定计划,这个是很重要的,所以要花些时间,以避免做出的东西不符合需求,而导致返工。
当需求明白后,就可以开始编码了,开发过程中要做到和团队成员实时沟通,以确保开发中需求的准确性。
编码时要注意编码规范,和多写有用注释,以方便自己和别人以后阅读查看,同时为以后测试和维护降低难度。
在开发过程中肯定会多多少少遇到难以攻克的技术问题,首先自己可以先查查资料研究一下,在时间允许的范围内能解决最好,同时也可以请其他组员或同事帮助指导。如果解决不了,要即时向组长汇报,请求技术支持,或进行进度计划调整,以确保不耽搁项目进度。
项目开发中经常会是团队开发,这样就涉及到程序的版本控制问题,简单的就是明确分工,公用的代码由一个人统一管理。其次就是借助版本管理工具来管理,以避免文件的覆盖,脏读,重复等问题。以提高开发效率。
和后台文件整合时
导入后台部分项目,出现不能解析 springframework 字样。
产生原因:
创建项目时没有正常下载 maven 的依赖。
解决方案:
图 47 Maven
在项目设计过程中不会与数据库进行连接
产生原因:
对数据库技术不太熟悉,JS 相关技术不太熟悉。
解决方案:
let conn = mysql.createConnection({
})
调用 MySQL 模块中的 connect 方法,连接 MySQL 数据库
conn.connect()
编写一个查询语句 SQL,以字符串形式赋值给变量 SQL
最后调用 query()方法,通过返回的值进行判断,然后打印返回成功的值
conn.query(sql, function(err,res)) {
if(err) {
console.log(‘连接失败’)
}
console.log(res)
}
var stuId = document.getElementById(‘stuId1’).value;
var name= document.getElementById(‘name1’).value;
通过 document.getElementById(‘object’).value 获取输入框中的数据
将数据写入表格
var iTr = document.createElement(‘tr’);
创建 tr 标签,即创建行
var iTd1 = document.createElement('td');
iTd1.className = "col1";
iTd1.appendChild(sel);
创建 td 标签,即创建单元格,并将数据加入单元格
iTable.appendChild(iTr);
iTr.appendChild(iTd1);
在项目开发期间,积极和团队成员进行交流,确保每一天都能了解团队成员前一天的开发进度,确保和每位团队成员进度持平,积极和每位团队成员进行沟通,合理安排分工,团队成员有关项目开发的问题小组内会积极讨论,确保解决每位成员遇到的问题,保证了个人项目开发目标的完成。
通过本次课程设计,收获到了比以往理论课还要大的收益。对项目中使用的一些技术有了更加充分的了解,通过编写代码,对这些技术有了更加充分的了解,也提升了自己的编码能力,由于时间仓促及本人的能力有限,系统还有很多不尽人意的地方,比如说,界面不够美观,有些功能还不够强大和完善,代码的重用性不够高,一些细节的问题还没有解决,这些都需要平时经验的积累和对技术的熟练掌握,希望在以后的工作学习中能进一步提高。系统在设计过程中,难免存在不足之处,使得本系统方案仍存在许多有待完善和改进的地方,比如说,在程序结构上系统设计的还不够紧密,对一些问题,如数据库的设计上没有统一,造成部分数据冗余,其次,安全性上考虑的不够仔细,比如说,没有考虑到跨平台可能面临的一些并发性问题、数据共享问题,多个用户会同时访问主页,会造成服务器端网络的阻塞,致使系统性能的下降,比如说,数据的备份与恢复。
通过本次实验,我意识到团队合作的重要性,在刚开始分工的时候,我们一定要分工明确,避免一个人任务过重,而其他人无事可做,而且团队之间要相互配合,互相了解对方所写的内容,这样在进行最后的项目整合的时候,才能按时完成,正确整合。
在以后的软件开发中首先应该注意项目的设计,数据库要定下来,基本流程已经确定,还有所使用的技术最好也确定下来,这样在软件开发过程中能避免走很多弯路,实际缩短项目开发的时间;还有要注意设计变化和需求变化,需求的变化往往是最致命的,意味着项目的某些部分得重新推倒重来,如果这个部分跟已完成的多个部分有牵连的话,更容易增加开发成本,而设计变化的话,软件开发人员的水平就决定了项目的好坏。下来就要注意代码编写,因为是小组分工,所以我们要强调团队合作性。那么你写的代码使得别人要能够看懂,我们必须在实际的编写代码过程中要有详细的编码规范,以下的一些规范是我们必须要遵守的:
开发人员的测试,是保证代码能正常运行,在开发时候发现的错误往往比较容易修正。但是一旦软件到了测试小组那里出了问题,那么就多了很多时间来修正 BUG。另外开发人员的测试除了保证代码能正常运行以外,还有一个很重要的方面就是要保证上次能正常运行的代码,这次还是能正常运行。如果做不到这点,那么 BUG 就不断的会出现,很多 BUG 也会反复出现。于是软件看上去就有修补不完的 BUG 了。所以要保证能正常运行上次代码。
我在课程设计中主要负责系统管理员登录管理界面和部分学生登录方面的网页开发及设计,开发以及系统用例的测试,网页模块包括:班级管理、成绩管理、教师管理、课程管理、学生管理,管理员部分。
班级管理主要分为两个页面,一个页面为输入班级信息锁定班级,输入的信息包括班级教师姓名、班级总人数和备注信息,班级序号为每个班级的固定值不可以被改变。输入完信息后,查询到固定的一个班级并且跳转到另一个页面,操作班级数据信息的页面,在这个页面可以进行从数据库增加、删除、修改、查询班级的数据(班级总人数、教师姓名、备注信息),操作完成后可以进行其他模块的管理。
学生管理部分的两个页面中,一个页面为输入学生信息以及学生所在班级锁定学生个人,输入的信息包括学生姓名、学生所在班级序号和备注,学生序号为固定值不可以被改变。输入完信息后,查询到固定的一个学生并且跳转到另一个页面,操作学生数据信息的页面,在这个页面可以进行从数据库增加、删除、修改、查询学生的数据(姓名、学生所在班级序号),操作完成后可以进行其他模块的管理。
教师管理部分的两个页面中,一个页面为输入教师信息锁定教师个人,输入的信息包括教师姓名、教师所在班级序号和备注信息,教室序号为固定值不可以被改变。输入完信息后,查询到固定的一个教师并且跳转到另一个页面,操作教师数据信息的页面,在这个页面可以进行从数据库增加、删除、修改、查询教师与班级匹配的数据(教师姓名、所带的班级),操作完成后可以进行其他模块的管理。
课程管理部分的两个页面中,一个页面为输入课程信息锁定课程,输入的信息包括课程名称、课程序号和备注信息。输入完信息后,查询到固定的一个课程并且跳转到另一个页面,操作课程数据信息的页面,在这个页面可以进行从数据库增加、删除、修改、查询课程的数据(课程名称、课程序号),操作完成后可以进行其他模块的管理。
成绩管理部分的两个页面中,一个页面为输入学生信息锁定学生,输入的信息包括学生姓名、学生所在班级序号和成绩。输入完信息后,查询到固定的一个班级并且跳转到另一个页面,操作学生成绩数据信息的页面,在这个页面可以进行从数据库增加、删除、修改、查询学生成绩的数据(学生姓名、所在班级序号、成绩),操作完成后可以进行其他模块的管理。
图 49 管理页面总览
图 50 detail 页面总览
图 51 成绩管理操作数据页面
大小: 9.80MB
➡️ 资源下载:https://download.csdn.net/download/s1t16/87516543
注:如当前文章或代码侵犯了您的权益,请私信作者删除!