Java课程设计——学生成绩管理
一、项目简介
- 功能描述:系统用以管理学生成绩等相关信息,支持用户登录,数据采用数据库存储,可对学生成绩等相关信息进行增删查改,支持分别对所有学生各科成绩画出柱状分布图,能随机生成10万条测试数据写入数据库和文本文件(每科成绩以80分为中心正太分布)。
- 个人负责任务:GUI界面设计,数据库连接,功能1、2、8。
二、功能架构图
三、git提交记录
四、个人任务介绍
1. GUI界面设计 ![](https://img2023.cnblogs.com/blog/2991838/202301/2991838-20230110201514154-1656928101.png)
2. 数据库连接
数据库连接采用mysql连接
导入jar包
3. 添加学生信息
添加学生时利用sql语句,在数据库里加入学生的姓名、学号、出生年月日、性别这四项信息,其他信息输入时设为null。
public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getActionCommand().equals("add")) { //添加学生信息 Model tmp = new Model(); String sql = "insert into stu values(?,?,?,?,null,null,null,null,null)"; System.out.println(Integer.valueOf(a)+nameTxt.getText()+ sexTxt.getText()+dateTxt.getText()); String []paras = {a,nameTxt.getText(),sexTxt.getText(),dateTxt.getText()}; //String.valueOf(Double.parseDouble(MathTxt.getText())+Double.parseDouble(JavaTxt.getText())+Double.parseDouble(PETxt.getText())), // String.valueOf((Double.parseDouble(MathTxt.getText())+Double.parseDouble(JavaTxt.getText()))+Double.parseDouble(PETxt.getText())/3)}; if(!tmp.cudStu(sql, paras)) JOptionPane.showMessageDialog(this, "添加学生信息失败"); //关闭窗口 this.dispose(); } else if(e.getActionCommand().equals("cancel")) { //关闭窗口 this.dispose(); } }
运行展示
4. 录入学生成绩
添加学生成绩需要实现从数据库表中姓名所在列的信息提取到结果集,还要建立JTextField类型的数组,存取从文本框输入的成绩,然后利用数据库的数据的批量更新,更新数据库中某一科成绩为从文本框中输入的数据,而且只有在三门成绩都有成绩之后,系统自动更新总分数和平均分。
只给出某一科的代码,其他科目与之相似
if (flag == 1) { if (e.getActionCommand().equals("add")) { // 添加学生成绩 String sql = "update stu set stuMath=? where stuName =?"; PreparedStatement ps = null; try { ps = con.prepareStatement(sql); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } for (int i = 0; i < Txts.size(); i++) { try { ps.setObject(2, list.get(i)); ps.setObject(1, Txts.get(i).getText()); ps.executeUpdate(); } catch (SQLException e1) { e1.printStackTrace(); } } String sql1 = "update stu set stuCount=? ,stuAvg=? where stuName=?"; try { ps = con.prepareStatement(sql1); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } double count = 0.0, avg = 0.0; for (int i = 0; i < Txts.size(); i++) { try { if (Java.get(i) != null) { if (PE.get(i) != null) { count = Double.parseDouble(Txts.get(i).getText()) + Double.parseDouble(Java.get(i)) + Double.parseDouble(PE.get(i)); avg = count * 1.0 / 3; ps.setObject(1, count); ps.setObject(2, avg); ps.setObject(3, list.get(i)); ps.executeUpdate(); } } } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } } else if (e.getActionCommand().equals("cancel")) { // 关闭窗口 this.dispose(); }
运行结果
5. 随机生成10万条测试数据
随机生成10万条测试数据,要多次运用Random,需要随机生成学号(唯一)、性别、出生年月日、成绩(以80为中心成正态分布)、姓名(根据性别有所不同),将生成的学生的信息写入txt文件,并采用insert into语句将随机生成的学生信息存入数据库里面。
随机生成学号且学号唯一
// 随机生成学号且不重复 public static String generateRandom(int length) { Random random = new Random(); char[] digits = new char[length]; digits[0] = (char) (random.nextInt(9) + '1'); for (int i = 1; i < length; i++) { digits[i] = (char) (random.nextInt(10) + '0'); } return new String(digits); }
随机生成成绩
// 随机生成成绩以80分为中心成正态分步 // 随机生成成绩时,使用nextGaussian()方法生成N(0,1)标准正太分布,逆用正太分布标准化公式将其乘标准差8再加期望80,得到N(80,64)正态分布。 public static Double getSorce() { Random r = new Random(); double score = Math.rint(8 * r.nextGaussian() + 80); if (score > 100) { score = 100.0; } return score; }
随机生成性别
// 随机生成性别 public static String getGender() { Random random = new Random(); int i = random.nextInt(2);// 设置产生的男女比例 产生数据的范围(0,1,2) if (i == 0) { return "女"; } else { return "男"; } }
随机生成姓名
// 随机生成姓名(根据性别不同而有不同) public static String getName(String gender) { Random random = new Random(); String[] Surname = { "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "尹", "任", "刘", "曲", "纪", "许", "何", "张", "庞", "段", "郝", "徐", "秦", "黄", "谢" }; String girl = "秀娟英艳丽华惠巧翠花心仪芬芳彩娥云朵春蓝秋菊凤萱"; String boy = "雄伟刚毅强轩宇健康国庆福辉保文军顺源元塬明鑫贤献东"; int index = random.nextInt(Surname.length - 1); String name = Surname[index];// 获取一个姓氏 if (gender.equals("女")) { int j = random.nextInt(girl.length() - 2); if (j % 2 == 0) { name = name + girl.subSequence(j, j + 2); } else { name = name + girl.subSequence(j, j + 1); } return name; } else { int j = random.nextInt(girl.length() - 2); if (j % 2 == 0) { name = name + boy.subSequence(j, j + 2); } else { name = name + boy.subSequence(j, j + 1); } return name; } }
随机生成出生年月日
public static String getBirthday() { Random r = new Random(); int day = r.nextInt(365 * 4) + 365 * 19; Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_MONTH, -day); return calendar.get(Calendar.YEAR) + String.format("-%02d", (calendar.get(Calendar.MONTH) + 1)) + String.format("-%02d", (calendar.get(Calendar.DAY_OF_MONTH))); }
将生成的数据存入文件和数据库
private void generateTestDatajButtonActionPerformed(ActionEvent evt) throws IOException { String sql = "insert into stu values(?,?,?,?,?,?,?,?,?)"; int num = 100000; System.out.println(num); DecimalFormat df = new DecimalFormat("#0.0"); try { File writeName = new File("C:\\Users\\Nanmu\\Desktop\\output.txt"); writeName.createNewFile(); try (FileWriter writer = new FileWriter(writeName); BufferedWriter out = new BufferedWriter(writer)) { for (int i = 1; i <= num; i++) { String id = generateRandom(9); String gender = getGender(); String name = getName(gender); String birthday = getBirthday(); double math = getSorce(); double java = getSorce(); double PE = getSorce(); double totalSorce = math + java + PE; double avg = totalSorce / 3; out.write(id + "," + name + "," + gender + "," + birthday + "," + df.format(math) + "," + df.format(java) + "," + df.format(PE) + "," + df.format(totalSorce) + "," + df.format(avg) + "\r\n"); System.out.println(id + "," + name + "," + gender + "," + birthday + "," + df.format(math) + "," + df.format(java) + "," + df.format(PE) + "," + df.format(totalSorce) + "," + df.format(avg)); out.flush(); String[] paras = { id, name, gender, birthday, df.format(math), df.format(java), df.format(PE), df.format(totalSorce), df.format(avg) }; if (!tmp.cudStu(sql, paras)) JOptionPane.showMessageDialog(this, "录入学生信息失败"); // 关闭窗口 this.dispose(); } JOptionPane.showMessageDialog(null, "生成数据成功"); } } catch (IOException e) { JOptionPane.showMessageDialog(null, "生成数据时发生错误"); } }
运行结果
五、不足与展望
不足:1)在书写录入学生成绩时,按列输入成绩代码有些冗余,虽然可以实现相关功能,但是我觉得代码结果还需要极大的改善,而且录入成绩的GUI界面做的不大美观,需要继续努力学习实现GUI界面的美化。
2)随机生成10万数据的过程很慢,需要等待的时间较长,这部分还需要进行改善。
展望:总的来说,这次课设的经历还是收获满满,学习到很多知识,虽然遇到很多困难,但是都尽最大的努力将其改对,希望以后更够更加熟练的掌握Java的相关知识,学习美化GUI界面,还有如何加快将数据加入数据库的速度。