本周参加了JAVA程序设计的实训周,当时老师一共分发了4个项目选题:学生管理系统、图书管理系统、财务管理系统,学生成绩管理系统(这个有点不确定了)。要求一个人一个项目,一共4天的开发工期,星期五答辩。我一眼就看中了“图书管理系统”,头脑中迅速构建出了基本架构。
开发的环境和工具:JDK1.8、eclipse 2018-9、mysql-8.0.17-winx64、Navicat for MySQL
图书管理系统的基本功能:查询在馆图书、查询所有图书、借书、还书、借阅记录、图书入库、图书出库、图书检索等等。
一个管理系统大致可以分为两个方面:前端与后端。前端就是系统的界面,专门展示给用户看的;后端就是系统内部的算法,就好比一个图书检索的功能,展示给用户的只是一个图书检索的按钮,而后端实现的就是如何去检索,当然后端还包括很多,连接数据库也是其中一部分。
构建算法框架:在分析完功能需求和所涉及到的知识领域之后,就可以开始动工了。说干就干,我一开始就构建出功能实现的算法框架,包括查询图书、借书、还书、图书入库、图书出库等一系列功能的基本框架,也配置了JDBC连接数据库。在连接数据库这里,比较简单,不够也很容易遇到坑,在这里我推荐这篇教程:MySql的安装与初始化,这篇讲得很简洁,不难懂,当然还有很多坑这里就不多说了,遇到问题就百度。连接数据库如下:
// 声明Connection对象
Connection conn;
// 数据库把柄
Statement sql;
fun(){
// 配置数据库的连接
String url = "jdbc:mysql://127.0.0.1:3306/java_project?&useSSL=false&serverTimezone=GMT%2B8";
try {
conn = DriverManager.getConnection(url, "root", "123456");
System.out.println("数据库连接成功");
sql = conn.createStatement();
}
catch(SQLException e) {
System.out.println(e);
}
}
开发界面:功能算法框架实现后,我们就可以开始界面的开发工作了。由于之前系统地分析了功能模块,因此很快就根据需求构建出了界面。不过我本人是一个很有强迫症的人,界面必须做得很整齐,在调整组件位置上,我花了相对较多的时间,最后完成时,已经是实训的第2天了。在这天,班委给老师反映了一下情况,感觉一个人很难在一周完成项目的开发,所以最后决定3个人一组共同开发。不过考虑到我们组另外两位都是女生,我开发的速度稍微快点,所以最后决定我负责开发,她们分别负责写文档和答辩。
功能算法与组件的对接:这一块是我最喜欢的,因为没有功能算法的组件是没有灵魂的(没有对接算法的按钮,毕竟都点不动)。这是最有趣的,同时也是最费时间的,中途遇到了不少的问题,涉及了很多以前都没有用过的知识:java swing组件的各种监听事件(虽然高中学过类似的,不过很多不一样了)、java处理字符串的一些算法…这些实际上都还好,最让我头疼的还是前端与后端传参的问题,因为我考虑的前端界面,主要是分为两个(管理员端和学生端),所以构建的界面不一样,当然传的参数也有所不同,因此总结出来一句话,开发时一定要有清晰的头脑,不然你自己都不知道参数需要传哪些了(我没有清晰的头脑,所以在哪些不写注释的大佬目前自愧不如,还是写上注释吧)。
功能的测试与完善:到这里,已经是第4天了,也就是实训的最后一天。因为我是一个比较需要扣细节的人,所以在每个功能上花了很多时间,到最后一天时,实际上还没有做多少功能。目前为止做了:登录与注册界面、学生端的图书检索、借书与还书,管理员端的图书入库与出库。在下午时,我把每个功能模块都调试了一遍,本来认为可以收工了,但是没有想到啊,突然我们组的同学告诉我,还少了借阅的时间记录和借阅图书的记录。当时就觉得,程序猿真不容易啊,加不加班就等“项目经理”一句话。那还能怎么办,最后重新创建了一个保存借阅记录的表,每个用户借书之后,都把学生信息和图书信息以及当前借书时间保存到此表中,最后学生端根据学生学号查询,管理员端可查询所有学生的借书记录。
String[][] Query_history(String SQL){
String[][] tableValues = {};
try {
ResultSet result = sql.executeQuery(SQL);
result.last();
int row = result.getRow();
tableValues = new String[row][6];
ResultSet result2 = sql.executeQuery(SQL);
for(int i = 0;result2.next();i++) {
for(int j = 0;j < 6;j++) {
tableValues[i][j] = result2.getString(j + 1);
}
}
}
catch(SQLException e) {
System.out.println(e);
}
return tableValues;
}
在第4天晚上,功能终于比较完善了,虽然功能不是很多,不过本人也尽力了,的确一个人开发速度有点跟不上。
附上部分效果图:
登录与注册界面
管理员端——所有人的借阅记录
管理员端——查询在馆图书
图书入库
最后答辩时,老师指明了几个不足之处:没有限定还书期限、图书入库的编号问题、图书的分类、缺少游客模式。不得不说,在答辩之前,我还多有信心的,答辩时,才发现原来还有这么多的问题。此时系统的缺陷虽然挺多的,不过也刚好是进步空间,抱着完善系统的心理,我又进一步开发了借书期限的控制(20天)、游客模式、搜索的模糊查询。
图书管理系统升级版功能:
借书期限控制
为什么借书期限为20天呢?我准备用30天的,结果才借阅的图书,居然都逾期20多天了,带着疑惑的心情把限定的期限时间打印出来,看惊了!
// 计算还书期限
String DueTime(String lentime) throws ParseException {
// 借阅时间限制为20天
long limitDay = 30 * 1000 * 60 * 60 * 24;
System.out.print(limitDay);
// 获取当前时间
Date d = new Date(System.currentTimeMillis());
// 获得当前时间的毫秒形式
SimpleDateFormat mat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss aa");
String nowtime = mat.format(d);
// 借书时间+借阅时间限制(毫秒) 得到图书到期时间
long duetime = mat.parse(lentime).getTime() + limitDay;
// 图书到期时间-当前时间 得到还书期限(毫秒)
long m = duetime - mat.parse(nowtime).getTime();
long hour = 0;
long day = 0;
long minute = 0;
if(m < 0 && m > -3600000)
return "已逾期 :" + String.valueOf(-(m / (1000 * 60))) + "分";
else if(m < -3600000 && m > -86400000) {
hour = m / (1000 * 60 * 60); // 计算有多少个小时
return "已逾期 :" + String.valueOf(-hour) + "小时 " + String.valueOf(-((m - (hour * 1000 * 60 * 60)) / (1000 * 60))) + "分";
}
else if(m < -86400000 && m > -2592000000L) {
day = m / (1000 * 60 * 60 * 24); // 计算有多少天
hour = (m - day * 1000 * 60 * 60 * 24) / (1000 * 60 * 60);
minute = (m - (day * 1000 * 60 * 60 * 24) - (hour * 1000 * 60 * 60)) / (1000 * 60);
return "已逾期 :" + String.valueOf(-day) + "天 " + String.valueOf(-hour) + "小时 " + String.valueOf(-minute) + "分";
}
else if(m < -2592000000L)
return "已超时";
else if(m < 3600000) // 一小时以内
return String.valueOf(m / (1000 * 60)) + "分";
else if(m < 86400000) { // 一天以内
hour = m / (1000 * 60 * 60); // 计算有多少个小时
return String.valueOf(hour) + "小时 " + String.valueOf((m - (hour * 1000 * 60 * 60)) / (1000 * 60)) + "分";
}
else if(m < 2592000000L) { // 一个月以内
day = m / (1000 * 60 * 60 * 24); // 计算有多少天
hour = (m - day * 1000 * 60 * 60 * 24) / (1000 * 60 * 60);
minute = (m - (day * 1000 * 60 * 60 * 24) - (hour * 1000 * 60 * 60)) / (1000 * 60);
return String.valueOf(day) + "天 " + String.valueOf(hour) + "小时 " + String.valueOf(minute) + "分";
}
return "超出一个月";
}
简直不敢相信,不过仔细一想,有没有可能是因为超出了long类型的表示范围。通过我的一步步测试,发现当在第25天时,就已经不能正常表示了,下图为24天时的毫秒数:
作为一个典型的强迫症选手来说,怎么能写24呢,于是就20天吧。当然这里超出表示范围的问题,可以用一定的方法解决,不过由于马上期末考试了,就不考虑了。
图书检索的模糊查询
// 查询书籍
String[][] Query_book(String book_name, int flag) {
String[][] tableValues = {};
try {
ResultSet result = sql.executeQuery("select * from books where book_name like \'%" + book_name + "%\'");
result.last();
int row = result.getRow();
tableValues = new String[row][4];
ResultSet result2 = sql.executeQuery("select * from books where book_name like \'%" + book_name + "%\'");
for(int i = 0;result2.next();i++) {
for(int j = 0;j < 4;j++) {
if(j + 1 == 3 && !result2.getString(3).equals("0") && flag == 2) // 如果为管理员,则能看到图书去向
tableValues[i][j] = result2.getString(j + 1);
else if(j + 1 == 3 && !result2.getString(3).equals("0"))
tableValues[i][j] = "不在馆";
else if(j + 1 == 3)
tableValues[i][j] = "在馆";
else
tableValues[i][j] = result2.getString(j + 1);
}
}
}
catch(SQLException e) {
System.out.println(e);
}
System.out.print(tableValues.length);
return tableValues;
}
// 重载 查询书籍
String[][] Query_book(int book_id, int flag) {
String[][] tableValues= {};
try {
ResultSet result = sql.executeQuery("select * from books where book_id like \'%" + book_id + "%\'");
result.last();
int row = result.getRow();
tableValues = new String[row][4];
ResultSet result2 = sql.executeQuery("select * from books where book_id like \'%" + book_id + "%\'");
for(int i = 0;result2.next();i++) {
for(int j = 0;j < 4;j++) {
if(j + 1 == 3 && !result2.getString(3).equals("0") && flag == 2) // 如果为管理员,则能看到图书去向
tableValues[i][j] = result2.getString(j + 1);
else if(j + 1 == 3 && !result2.getString(3).equals("0"))
tableValues[i][j] = "不在馆";
else if(j + 1 == 3)
tableValues[i][j] = "在馆";
else
tableValues[i][j] = result2.getString(j + 1);
}
}
}
catch(SQLException e) {
System.out.println(e);
}
return tableValues;
}
游客登录
以上三点就是本次升级的内容,总的来说比较完善,关于图书信息的不全(如作者、出版社等等)、图书分类编号等问题,因为本人期末,就不多弄了,有兴趣的朋友可以下载源码,进行参考完善。项目代码
随后我将会推出java swing应用程序打包成exe文件并发布到其他电脑远程连接数据库运行的文章,感谢支持。
来源:CSDN
作者:向程序猿蜕变的苦逼人类
链接:https://blog.csdn.net/qq_35149975/article/details/103838931