简单Java项目选课管理系统:从零开始构建学生选课流程
在当今信息化教育环境中,高校和培训机构对学生成绩、课程安排、选课管理的需求日益增长。开发一个简单Java项目选课管理系统不仅有助于理解面向对象编程(OOP)的核心思想,还能为后续复杂系统的扩展打下坚实基础。本文将详细介绍如何使用Java语言结合基本的数据库操作(如MySQL),设计并实现一个功能完整但结构清晰的学生选课系统。
一、项目目标与功能需求分析
本系统的初衷是帮助学生在线完成课程选择,同时让教师或管理员能够查看选课情况、管理课程信息。主要功能包括:
- 用户登录(学生、教师、管理员三类角色)
- 学生可浏览可选课程列表并进行选课/退课操作
- 教师可查看自己所授课程的学生名单
- 管理员可添加、修改、删除课程信息
- 数据持久化存储(通过JDBC连接MySQL数据库)
该系统虽“简单”,但覆盖了典型的CRUD(增删改查)操作、权限控制、事务处理等关键知识点,适合初学者练手。
二、技术栈选择与环境搭建
为了保证项目的可移植性和学习价值,我们采用以下技术组合:
- 开发工具:IntelliJ IDEA 或 Eclipse(推荐IDEA,语法高亮和调试更友好)
- 编程语言:Java SE 8+(支持Lambda表达式提升代码简洁度)
- 数据库:MySQL 5.7+(本地部署或Docker容器均可)
- 驱动包:mysql-connector-java(用于JDBC连接)
- 依赖管理:Maven(便于引入第三方库和版本控制)
安装完成后,需在MySQL中创建名为course_system的数据库,并建立以下四张表:
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(100) NOT NULL,
role ENUM('student', 'teacher', 'admin') NOT NULL
);
CREATE TABLE courses (
id INT PRIMARY KEY AUTO_INCREMENT,
course_name VARCHAR(100) NOT NULL,
teacher_id INT,
max_students INT DEFAULT 30,
current_enrollment INT DEFAULT 0,
FOREIGN KEY (teacher_id) REFERENCES users(id)
);
CREATE TABLE enrollments (
id INT PRIMARY KEY AUTO_INCREMENT,
student_id INT NOT NULL,
course_id INT NOT NULL,
enrollment_date DATE NOT NULL,
FOREIGN KEY (student_id) REFERENCES users(id),
FOREIGN KEY (course_id) REFERENCES courses(id),
UNIQUE(student_id, course_id)
);
三、核心模块设计与实现
1. 用户认证模块
用户登录功能是整个系统的入口。我们需要编写一个LoginService类来验证用户名密码是否匹配,并返回对应的角色信息:
public class LoginService {
private Connection conn;
public LoginService() throws SQLException {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/course_system", "root", "password");
}
public User login(String username, String password) throws SQLException {
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username=? AND password=?");
stmt.setString(1, username);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
return new User(rs.getInt("id"), rs.getString("username"), rs.getString("role"));
}
return null;
}
}
2. 学生选课模块
学生选课逻辑涉及两个步骤:首先检查课程容量是否已满;其次插入选课记录。这里用到事务控制防止脏读或重复选课:
public boolean enrollStudent(int studentId, int courseId) throws SQLException {
conn.setAutoCommit(false);
try {
PreparedStatement checkStmt = conn.prepareStatement("SELECT current_enrollment, max_students FROM courses WHERE id=?");
checkStmt.setInt(1, courseId);
ResultSet rs = checkStmt.executeQuery();
if (!rs.next() || rs.getInt("current_enrollment") >= rs.getInt("max_students")) {
conn.rollback();
return false;
}
PreparedStatement updateStmt = conn.prepareStatement("UPDATE courses SET current_enrollment=current_enrollment+1 WHERE id=?");
updateStmt.setInt(1, courseId);
updateStmt.executeUpdate();
PreparedStatement insertStmt = conn.prepareStatement("INSERT INTO enrollments (student_id, course_id, enrollment_date) VALUES (?, ?, CURDATE())");
insertStmt.setInt(1, studentId);
insertStmt.setInt(2, courseId);
insertStmt.executeUpdate();
conn.commit();
return true;
} catch (SQLException e) {
conn.rollback();
throw e;
} finally {
conn.setAutoCommit(true);
}
}
3. 教师与管理员模块
教师可查看自己的授课班级,管理员则拥有最高权限:
public List getCoursesByTeacher(int teacherId) throws SQLException {
PreparedStatement stmt = conn.prepareStatement("SELECT c.*, u.username AS teacher_name FROM courses c JOIN users u ON c.teacher_id=u.id WHERE c.teacher_id=?");
stmt.setInt(1, teacherId);
ResultSet rs = stmt.executeQuery();
List courses = new ArrayList<>();
while (rs.next()) {
Course course = new Course();
course.setId(rs.getInt("id"));
course.setCourseName(rs.getString("course_name"));
course.setTeacherName(rs.getString("teacher_name"));
course.setMaxStudents(rs.getInt("max_students"));
course.setCurrentEnrollment(rs.getInt("current_enrollment"));
courses.add(course);
}
return courses;
}
public void addCourse(String courseName, int teacherId, int maxStudents) throws SQLException {
PreparedStatement stmt = conn.prepareStatement("INSERT INTO courses (course_name, teacher_id, max_students) VALUES (?, ?, ?)");
stmt.setString(1, courseName);
stmt.setInt(2, teacherId);
stmt.setInt(3, maxStudents);
stmt.executeUpdate();
}
四、界面设计与交互优化
虽然这是一个命令行版本,但我们可以通过菜单驱动的方式模拟图形化体验:
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("\n=== 选课管理系统 ===");
System.out.println("1. 登录");
System.out.println("2. 退出");
System.out.print("请选择:");
int choice = scanner.nextInt();
switch (choice) {
case 1:
// 执行登录逻辑
break;
case 2:
System.out.println("再见!");
return;
default:
System.out.println("无效选项,请重试。");
}
}
对于进阶学习者,可以进一步封装为Swing GUI或Spring Boot Web应用,提升用户体验。
五、常见问题与解决方案
- 数据库连接失败?请确认MySQL服务正在运行,且账号密码正确。
- 出现重复选课?务必在数据库中设置唯一约束(UNIQUE(student_id, course_id))。
- 事务未回滚?确保在异常捕获后手动调用
conn.rollback()。 - 性能瓶颈?若课程数量庞大,建议引入缓存(如Redis)或分页查询。
六、总结与延伸建议
这个简单的Java项目选课管理系统虽然是教学性质的作品,但它涵盖了现代软件开发的基本要素:用户认证、数据持久化、业务逻辑封装、异常处理和事务控制。它不仅是学习Java SE的好起点,也为未来转向Spring Boot、MyBatis等框架提供了良好过渡。
下一步建议:
- 接入前端框架(如Vue.js + Axios)打造前后端分离架构
- 集成日志系统(SLF4J + Logback)便于调试和监控
- 添加单元测试(JUnit)保障代码质量
- 部署至Linux服务器并通过Docker容器化运行
总之,从一个小项目出发,逐步完善功能,才是成长为一名合格Java工程师的有效路径。

