ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Java学生信息管理系统课设实战:JDBC+控制台+MySQL完整教程

Java学生信息管理系统课设实战:JDBC+控制台+MySQL完整教程 简介一套基于Java控制台与MySQL实现的学生信息管理系统项目包面向Java初学者、课程设计学生以及需要快速搭建控制台应用的开发者。系统为单管理员模式登录后即可对学生信息进行增删改查操作整体结构简洁清晰适合理解JDBC编程与控制台菜单交互。压缩包共33个文件大小约37.67MB内含6个Java源码、6个class编译文件、3份SQL数据库脚本、3个JDBC连接jar包、9张运行截图、1份技术说明书、1个演示视频以及运行必读txt覆盖从环境配置、数据库导入到代码运行、效果演示的完整链路。目前已有66人次浏览学习。通过该资源读者可得到可直接导入Eclipse运行的完整工程借助演示视频和截图快速跑通增删改查流程并参考技术说明书掌握表结构与项目设计思路附带的运行必读还能帮助解决常见环境问题为课程设计或毕业设计提供实际参考。1. 学生信息管理系统是什么从课设答辩到控制台交互的完整闭环学生信息管理系统大概是 Java 课程设计里出现频率最高的题目但大部分网上下到的版本要么是 Swing 界面过于老旧要么干脆跑不起来。这份资源走的是“java 控制台 mysql”路线用纯控制台交互完成学生、课程、成绩的增删改查核心代码量控制在一千行左右搭配演示视频把整个录入、查询、修改流程走了一遍。适合正在做 Java 课设、准备毕业设计、或者刚学完 JDBC 想找个完整案例练手的人。视频的价值在于把“能跑”和“能讲明白”对齐了——答辩时老师问你每一块代码是干什么的你能照着视频里的思路讲清楚这才是这份资源真正值得下载的地方。2. 环境与工程结构JDK 8 Eclipse MySQL 8 的版本匹配与初始化2.1 环境清单JDK、Eclipse、MySQL、驱动 jar 的选型基准拿到资源包后先别急着双击运行先检查环境。这项目用的是 java 控制台 mysql 三件套其中最容易翻车的就是 MySQL 版本和 JDBC 驱动不匹配。我建议的基准组合是这样的组件推荐版本说明JDK1.8课程设计和答辩环境兼容性最好Eclipse 2020 以后版本自带适配Eclipse2020-06 以上内置 JDBC 支持导入工程后可以直接跑MySQL5.7 或 8.0驱动用mysql-connector-java-8.0.x.jarJDBC 驱动8.0.x连接串里必须带serverTimezoneAsia/Shanghai操作系统Windows 10/11控制台程序无跨平台依赖Linux 也能跑选 JDK 8 不是因为它最新而是因为 Eclipse 搭配 JDK 8 的时候编译不报那些奇怪的“invalid target release”错误。MySQL 8.0 用mysql-connector-java-8.0.30这个版本的驱动兼容性比 5.1.x 好但要注意 8.0 驱动的连接串写法跟 5.1 有一条关键区别多了serverTimezone参数不写直接报The server time zone value Öйú±ê׼ʱ¼ä is unrecognized中文乱码加英文报错叠在一起新手直接蒙圈。资源包里如果自带了驱动 jar优先用包里的如果没带去 MySQL 官网下对应版本就行。2.2 从 Eclipse 导入工程到第一次编译通过的完整步骤先说导入步骤工程是标准的 Eclipse Java Project 结构不是 Maven也不是 Gradle所以不要用 “Import Maven Project” 去导会扑空。正确做法是# 解压资源包后确认目录结构 student-info-system/ src/ # Java 源码 lib/ # JDBC 驱动 jar sql/ # 建库建表脚本 doc/ # 演示视频、说明文档打开 Eclipse菜单栏选 File Import General Existing Projects into Workspace然后 Select root directory 指向解压出来的student-info-system文件夹。Eclipse 识别到.project文件后会显示项目名勾选后点 Finish。如果导入后源码报红叉最普遍的原因就是lib目录里的 jar 没被加载到 Build Path。右键项目 Build Path Configure Build Path Libraries Add JARs把lib下的mysql-connector-java-8.0.30.jar加进去。这里有个细节很多人在这一步用的是 Add External JARs指向自己下载的驱动结果是项目拷到别的电脑后路径失效运行直接ClassNotFoundException。用lib目录内引用的方式jar 跟工程走换机器也不怕。// 改完 Build Path 后顺手确认一下 JDK 编译级别 // 右键项目 Properties Java Compiler // 把 Compiler compliance level 设置为 1.8 // 如果报错 Java compiler level does not match就是这里没对齐配置完成后再编译一次能通过的话就说明环境和工程本身没问题接下来才是跑起来。2.3 工程的目录结构src、lib、sql、doc 各放什么看清楚目录结构对排查问题非常重要。这个项目的代码组织方式是典型的课设风格四个顶层目录各有职责src存放全部 Java 源码核心类是学生管理主程序里面包含连接数据库的工具方法、控制台菜单的显示逻辑、以及对学生表的增删改查操作。lib存放 JDBC 驱动 jar这个目录就是给 Eclipse 的 Build Path 用的项目里要引用的外部依赖都放这里别分散到系统盘的其他位置。sql存放建库脚本包括建数据库、建三张表、插入初始化数据的 SQL 语句用 Navicat 或 MySQL 命令行执行一遍就能把库准备好。doc存放演示视频和课程设计报告模板视频是 MP4 格式演示了从登录到完成所有操作的完整流程写文档的时候可以直接参考里面的操作截图。我一般会建议拿到资源后先打开sql里的脚本在建库之前把表名、字段名和 Java 代码里的 SQL 语句对照一遍。很多项目跑不起来的根源就是字段名对不上比如 Java 代码里写的是student_id但建表脚本里是sid第一遍执行必报Unknown column。先花五分钟做这个对照后面能省两小时。3. 数据库设计三张表撑起学生、课程、成绩的关联查询3.1 选择 MySQL Workbench 还是 Navicat 初始化数据库资源包里给了sql脚本理论上在 MySQL 命令行执行就行但实际操作用 Navicat 的人更多。MySQL 的安装教程网上已经很多了这里只说两个常见的坑装 MySQL 8.0 时如果选了 “Use Strong Password Encryption”Navicat 老版本连上去会报mysql_native_password相关的错需要把认证插件改回mysql_native_password另一个是端口别改默认 3306改了的话 Java 代码里的连接串也要同步改。执行脚本前先建好数据库控制台程序本身不会自动建库JDBC 连接串里的数据库名必须预先存在否则报Unknown database student_db。建库和建表分开两步做别指望一条命令全解决失败时定位也方便。3.2 表结构设计主键策略与外键约束学生信息管理系统最核心的是三张表学生表、课程表、成绩表。学生表存学号和姓名等基础信息课程表存课程编号和课程名成绩表是关联表同时存学生和课程的编号加上分数和学期字段。-- 学生表 CREATE TABLE student ( id INT NOT NULL AUTO_INCREMENT, student_no VARCHAR(20) NOT NULL UNIQUE, name VARCHAR(50) NOT NULL, gender VARCHAR(10) DEFAULT 男, major VARCHAR(50) DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 课程表 CREATE TABLE course ( id INT NOT NULL AUTO_INCREMENT, course_no VARCHAR(20) NOT NULL UNIQUE, course_name VARCHAR(100) NOT NULL, credit DECIMAL(3,1) DEFAULT 2.0, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 成绩表 CREATE TABLE score ( id INT NOT NULL AUTO_INCREMENT, student_id INT NOT NULL, course_id INT NOT NULL, score DECIMAL(5,2) DEFAULT 0.00, semester VARCHAR(20) DEFAULT NULL, PRIMARY KEY (id), KEY idx_student (student_id), KEY idx_course (course_id), CONSTRAINT fk_score_student FOREIGN KEY (student_id) REFERENCES student (id) ON DELETE CASCADE, CONSTRAINT fk_score_course FOREIGN KEY (course_id) REFERENCES course (id) ON DELETE CASCADE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;这段 SQL 里最关键的是外键的级联删除策略。成绩表依赖学生表和课程表删学生的时候如果没有ON DELETE CASCADEMySQL 会直接报Cannot delete or update a parent row: a foreign key constraint fails。加了级联之后删学生连带删除成绩符合课设场景下的业务预期。建表时我习惯把字符集单独写成utf8mb4而不是依赖 MySQL 默认配置。很多系统在 Windows 上装完 MySQL 默认字符集还是latin1这时候控制台输入中文进数据库存进去是乱码查出来也是乱码表现和代码乱码一模一样其实根源在表的字符集。写成utf8mb4能同时兼容中文和特殊符号一步到位。3.3 关联查询成绩列表的正确写法与常见误用控制台程序最常展示的界面就是“按学号查成绩”这个功能必须用三表关联查询直接查成绩表拿不到学生姓名。我在改学生信息管理系统的类似项目时见过有人为了省事先查学生表再查成绩表用两次查询拼数据效果能实现但代码冗余面试或答辩时老师追问一句“为什么不用 JOIN”就不好回答了。-- 按学号查询学生成绩列表 SELECT s.student_no AS 学号, s.name AS 姓名, c.course_name AS 课程, sc.score AS 成绩, sc.semester AS 学期 FROM student s INNER JOIN score sc ON s.id sc.student_id INNER JOIN course c ON c.id sc.course_id WHERE s.student_no ? ORDER BY sc.semester, c.course_no;这个查询语句是主程序里会被频繁调用的。用?占位符配合预处理语句Java 代码里用setString(1, studentNo)传参能防 SQL 注入。成绩表的id作为主键可以不加但索引idx_student和idx_course一定得有否则数据量上了几千条后按学号查成绩的响应速度会明显变慢。4. 代码主干JDBC 驱动加载、连接管理与控制台菜单的串联4.1 驱动加载和连接工具类为什么不用 DriverManager 裸连这个项目的代码主干是标准的 JDBC 流程也是课设答辩时的重点。看源码时会发现连接数据库的代码集中在工具类里而不是散落在各个业务方法中。这样设计的理由很朴素连接串里的 URL、用户名、密码只需要写一次修改时只需要改一个地方。package com.student.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class DBUtil { private static final String URL jdbc:mysql://localhost:3306/student_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai; private static final String USER root; private static final String PASSWORD 123456; private static Connection conn null; public static Connection getConnection() throws SQLException { try { Class.forName(com.mysql.cj.jdbc.Driver); conn DriverManager.getConnection(URL, USER, PASSWORD); return conn; } catch (ClassNotFoundException e) { throw new SQLException(MySQL驱动未找到检查lib目录下jar包, e); } } }注意驱动类名写的是com.mysql.cj.jdbc.Driver这是 MySQL 8.0 驱动的新类名。如果用 5.1 的老驱动类名是com.mysql.jdbc.Driver写错就报ClassNotFoundException。连接串里的characterEncodingutf8和serverTimezoneAsia/Shanghai这两个参数缺一不可前者解决中文乱码后者解决时区报错。这个工具类用的是最简单的单例模式整个程序运行期间只维持一个连接。控制台课设项目并发量极低一个连接够用但要注意getConnection()返回的Connection对象用完必须调用close()否则 MySQL 默认的wait_timeout到了之后连接会被服务端断开程序里再拿这个连接执行 SQL 就报Connection is not available或No operations allowed after connection closed。4.2 学生信息 CRUD预处理语句与 ResultSet 遍历核心功能是学生信息的增加、删除、修改和查询。控制台程序里面给出操作提示后通过Scanner读取用户输入然后调用 DAO 方法执行 SQL。这里用预处理语句而不是直接拼接字符串除了防注入还有一层好处处理包含中文的输入时不用考虑单引号转义问题。package com.student.dao; import com.student.util.DBUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Scanner; public class StudentDAO { // 增加学生 public void addStudent(Scanner sc) { System.out.print(请输入学号: ); String studentNo sc.nextLine(); System.out.print(请输入姓名: ); String name sc.nextLine(); System.out.print(请输入性别: ); String gender sc.nextLine(); System.out.print(请输入专业: ); String major sc.nextLine(); String sql INSERT INTO student(student_no, name, gender, major) VALUES(?, ?, ?, ?); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, studentNo); ps.setString(2, name); ps.setString(3, gender); ps.setString(4, major); int rows ps.executeUpdate(); System.out.println(rows 0 ? 添加成功 : 添加失败); } catch (SQLException e) { System.out.println(添加失败: e.getMessage()); } } // 按学号查询学生 public void findStudentByNo(String studentNo) { String sql SELECT student_no, name, gender, major FROM student WHERE student_no ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, studentNo); try (ResultSet rs ps.executeQuery()) { while (rs.next()) { System.out.println(学号: rs.getString(student_no) , 姓名: rs.getString(name) , 性别: rs.getString(gender) , 专业: rs.getString(major)); } } } catch (SQLException e) { System.out.println(查询失败: e.getMessage()); } } }这套代码用的是 try-with-resources 写法Connection、PreparedStatement、ResultSet都自动关闭不用手动写一堆finally。executeUpdate()返回受影响的行数大于 0 说明写入成功executeQuery()返回结果集用rs.next()游标遍历。注意getString(student_no)用的是列名不受 SELECT 列表顺序影响比getString(1)更稳妥。4.3 控制台菜单与事务操作成绩录入为什么必须开事务主程序的控制台菜单是一个while循环不断打印选项接收用户数字输入调用对应方法选 0 退出。这个结构是所有控制台项目的骨架看明白了就能改造成图书管理、员工管理等同类系统。package com.student.main; import com.student.dao.StudentDAO; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc new Scanner(System.in); StudentDAO studentDAO new StudentDAO(); while (true) { System.out.println( 学生信息管理系统 ); System.out.println(1. 添加学生); System.out.println(2. 查询学生); System.out.println(3. 录入成绩); System.out.println(4. 查询成绩); System.out.println(0. 退出); System.out.print(请选择: ); String input sc.nextLine(); int choice; try { choice Integer.parseInt(input); } catch (NumberFormatException e) { System.out.println(输入无效请输入数字); continue; } switch (choice) { case 1: studentDAO.addStudent(sc); break; case 2: System.out.print(请输入学号: ); studentDAO.findStudentByNo(sc.nextLine()); break; case 3: // 录入成绩时先根据学号找到学生再根据课程号找到课程最后写成绩表 // 这个过程分为两步查询和一步插入必须开启事务保证数据一致性 break; case 0: System.out.println(感谢使用再见); sc.close(); return; default: System.out.println(无效选项请重新输入); } } } }录入成绩在资源里是演示视频的重点片段。控制台引导用户输入学号和课程号然后录入分数写入成绩表。这个操作需要先验证学生号和课程号是否存在再插入记录两步查询一步写入如果不开启事务中途出错时数据会出现半完成状态。JDBC 里操作事务的方法是conn.setAutoCommit(false)执行完所有操作后conn.commit()出错时conn.rollback()代码主干里应该能看到这三个调用的成对出现。如果源码里没有这是值得自己补上的第一个改造点——答辩时主动讲“我在录入成绩时加了事务保证数据一致性”立刻比同组同学高出一个段位。5. 避坑指南驱动版本、中文乱码与连接池关闭的五个血泪记录5.1 mysql-connector-java 8.0 驱动类名和时区参数不匹配现象程序编译一切正常但一运行就报ClassNotFoundException: com.mysql.jdbc.Driver或者报The server time zone value Öйú±ê׼ʱ¼ä is unrecognized。原因MySQL 8.0 的驱动把驱动类名从com.mysql.jdbc.Driver改成了com.mysql.cj.jdbc.Driver同时连接串要求显式指定时区。5.1 驱动不要求serverTimezone8.0 驱动没有这个参数直接拒绝连接。解决驱动 jar 是 8.0 就用Class.forName(com.mysql.cj.jdbc.Driver)连接串加?serverTimezoneAsia/Shanghai。驱动是 5.1 就保持原来的类名两个不要混。判断驱动版本的方法是解压 jar 包看META-INF/MANIFEST.MF或者直接在 Eclipse 里看Referenced Libraries里文件名。5.2 控制台输出中文乱码的两层排查现象数据库表里的中文是正常的但控制台打印出来全是问号或者存入数据库后变成乱码。原因这个坑分两层。第一层是 Windows 控制台默认编码是 GBK而 Java 程序输出 UTF-8导致 System.out.println 打印中文乱码。第二层是 JDBC 连接串没带characterEncodingutf8写入数据库的中文被转成了错误编码。解决先查 Eclipse 的运行配置Run Configurations Common Console Encoding 改成 UTF-8或者直接给 JVM 加参数-Dfile.encodingUTF-8。再看连接串确保useUnicodetruecharacterEncodingutf8在 URL 里两个条件同时满足后中文显示才正常。血泪经验先改连接串再改控制台编码顺序别反否则你根本判断不了是哪一层出了问题。5.3 程序跑一会儿后报 “Connection is not available”现象刚启动时增删改查都正常操作四五次后突然报Connections could not be acquired from the underlying database程序必须重启才能恢复。原因DBUtil.getConnection()每次返回同一个静态Connection对象但使用方在 DAO 层把它close()了。MySQL 服务端检测到连接被关闭后下次再拿这个句柄执行 SQL 就报错。这是典型的“连接假关闭”问题。解决工具类维护的静态Connection不应该被业务层关闭两边职责分开。要么 DAO 层每次都getConnection()获取新连接用完彻底关掉要么工具类用单例模式统一管理DAO 层只调用close()但内部判断如果这个连接是复用的就直接忽略。我一般建议课设项目选第一种简单直接不产生踩坑机会。5.4 删除学生时外键约束报错现象控制台执行删除学生操作报Cannot delete or update a parent row: a foreign key constraint fails学生表里的记录删不掉。原因成绩表里的fk_score_student外键引用了学生表的主键删除学生时 MySQL 默认行为RESTRICT会阻止删除防止产生孤儿数据。解决建表时把外键的删除策略改成ON DELETE CASCADE这样删除学生成绩自动删除。如果资源包里的建表脚本没写级联就手动执行一条ALTER TABLE score DROP FOREIGN KEY fk_score_student再加新的级联外键改完再测试删除操作。这个坑在课设答辩时被问到的概率很高一定要提前处理。5.5 Navicat 连接 MySQL 8.0 报认证插件错误现象Navicat 连本地 MySQL 8.0 时弹窗报Client does not support authentication protocol requested by server; consider upgrading MySQL client连不上。原因MySQL 8.0 默认认证插件是caching_sha2_password旧版 Navicat 不支持这个插件。解决执行一条 SQL 把 root 用户的认证插件改回mysql_native_password# 在 MySQL 命令行或 Navicat 查询窗口执行 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码; FLUSH PRIVILEGES;改完后再刷新连接。这个坑跟 Java 代码本身无关但环境搭不好程序压根跑不起来属于隐藏的地雷。老版本 Navicat 破解安装包在网上流传很广但注意破解版有安全风险最好去官网下新版解决认证问题一劳永逸。6. 进阶验证把工具类改造成自己的 DBUtils 并加强数据校验资源里的代码能跑只是及格线我建议拿到后花一个晚上做一个改造把根上的连接管理换成“打开-使用-关闭”三段式工具类顺带把数据校验补上。改造后的工具类大致长这样package com.student.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class DBUtils { private static final String URL jdbc:mysql://localhost:3306/student_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai; private static final String USER root; private static final String PASSWORD 123456; // 获取连接 public static Connection getConnection() throws SQLException { try { Class.forName(com.mysql.cj.jdbc.Driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } return DriverManager.getConnection(URL, USER, PASSWORD); } // 释放资源先 ResultSet再 Statement最后 Connection public static void close(Connection conn, Statement stmt, ResultSet rs) { if (rs ! null) { try { rs.close(); } catch (SQLException e) { /* 关闭失败不影响主流程 */ } } if (stmt ! null) { try { stmt.close(); } catch (SQLException e) { } } if (conn ! null) { try { conn.close(); } catch (SQLException e) { } } } }这个版本的关键是把连接改成每次调用getConnection()都新建用完彻底关闭彻底杜绝上一章说的“假关闭”问题。释放顺序必须是 ResultSet 先关、Statement 其次、Connection 最后顺序颠倒或者漏关都会在数据量大时把连接数打满。顺手再改一下业务方法比如添加学生时先查重再插入学号不能用空字符串成绩数字必须在 0 到 100 之间。这些校验逻辑加在控制台输入之后、SQL 执行之前用一串if...else就能完成。做完这两个改造这个项目就从“能跑”变成了“禁得起问”答辩时你能讲的细节比看十遍视频都有用。验证改造是否成功的方式很简单反复执行增删改查二十次看有没有连接相关的报错插入一条中文名字的学生记录重启程序再查询确认中文读出来不乱码删除一个有关联成绩的学生确认成绩表跟着清空。三个验证都通过说明这个系统在你手里真正落稳了。从那以后我每次拿到课设代码都强制走一遍这套流程——先看环境版本再查建表脚本和代码字段一致性然后跑通核心 CRUD最后做一次小改造——这套习惯救了我无数次希望帮到你。本文还有配套的精品资源点击获取
返回列表