Java课程设计:学生信息管理系统
项目概述
本项目旨在开发一个基于 Java Swing 图形用户界面和 MySQL 数据库的学生信息管理系统,系统旨在实现对学生信息的增、删、改、查等基本操作,并具备良好的用户体验和健壮性,本设计将采用 MVC (Model-View-Controller) 设计思想,使代码结构清晰,易于维护和扩展。

技术栈
- 后端语言: Java (建议使用 JDK 8 或以上版本)
- GUI 库: Java Swing
- 数据库: MySQL 5.7 或 8.0
- 数据库连接: JDBC
- 开发工具: IntelliJ IDEA / Eclipse
系统功能设计
系统主要包含以下核心功能模块:
| 模块名称 | 功能描述 |
|---|---|
| 用户登录模块 | 提供管理员登录界面,验证用户名和密码,确保系统安全。 |
| 学生信息管理模块 | 核心功能 - 添加学生: 输入学生信息(学号、姓名、性别、年龄、专业、班级等),保存到数据库。 - 查询学生: 按学号、姓名或专业等条件进行单条件或多条件组合查询。 - 修改学生: 根据学号查找到学生,并修改其信息。 - 删除学生: 根据学号删除指定学生记录。 |
| 数据统计模块 | - 按专业统计: 显示各专业的学生人数。 - 按班级统计: 显示各班级的学生人数。 |
| 关于模块 | 显示系统的版本、作者、开发日期等信息。 |
数据库设计
我们需要在 MySQL 中创建一个数据库和一张学生信息表。
1 创建数据库
CREATE DATABASE student_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE student_db;
2 创建数据表
设计 student 表,包含学生基本信息。
CREATE TABLE `student` ( `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID', `student_id` VARCHAR(20) NOT NULL COMMENT '学号,唯一', `name` VARCHAR(50) NOT NULL COMMENT '姓名', `gender` VARCHAR(10) NOT NULL COMMENT '性别', `age` INT NOT NULL COMMENT '年龄', `major` VARCHAR(50) NOT NULL COMMENT '专业', `class_name` VARCHAR(50) NOT NULL COMMENT '班级', `phone` VARCHAR(20) DEFAULT NULL COMMENT '联系电话', `address` VARCHAR(200) DEFAULT NULL COMMENT '家庭住址', PRIMARY KEY (`id`), UNIQUE KEY `uk_student_id` (`student_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生信息表';
设计说明:

id: 自增主键,用于数据库内部操作。student_id: 学号,设置为唯一键,确保每个学生的学号不重复。- 其他字段如
name,gender,major等根据需求定义。
项目结构与 MVC 模式
为了遵循良好的编程规范,我们采用 MVC 模式组织代码。
StudentManagementSystem/
├── src/ # 源代码目录
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── sms/ # 项目主包
│ │ │ ├── controller/ # 控制器层:处理事件逻辑
│ │ │ │ ├── LoginController.java
│ │ │ │ └── MainController.java
│ │ │ ├── model/ # 模型层:数据模型和数据库操作
│ │ │ │ ├── Student.java
│ │ │ │ └── StudentDAO.java (Data Access Object)
│ │ │ ├── util/ # 工具类
│ │ │ │ └── DBUtil.java # 数据库连接工具类
│ │ │ ├── view/ # 视图层:所有GUI界面
│ │ │ │ ├── LoginView.java
│ │ │ │ ├── MainView.java
│ │ │ │ ├── AddStudentView.java
│ │ │ │ ├── UpdateStudentView.java
│ │ │ │ └── AboutView.java
│ │ │ └── Main.java # 程序入口
│ │ └── resources/
│ │ └── db.properties # 数据库配置文件
│ └── test/ # 测试代码目录 (可选)
├── lib/ # 第三方库目录 (如JDBC驱动)
└── README.md # 项目说明文档
核心代码实现
下面是各个核心类的代码示例。
1 数据库工具类 DBUtil.java
用于管理数据库连接,避免代码重复。
// src/main/java/com/sms/util/DBUtil.java
package com.sms.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class DBUtil {
private static String driver;
private static String url;
private static String username;
private static String password;
static {
try {
// 从db.properties文件中加载配置
Properties props = new Properties();
InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("db.properties");
props.load(is);
driver = props.getProperty("driver");
url = props.getProperty("url");
username = props.getProperty("username");
password = props.getProperty("password");
// 加载驱动
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("Failed to load database driver or configuration.");
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
public static void closeAll(Connection conn, Statement stmt, ResultSet rs) {
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
db.properties 文件内容 (放在 src/main/resources 目录下):
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/student_db?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8 username=root password=your_password
2 模型层 Student.java 和 StudentDAO.java
Student.java (实体类):
// src/main/java/com/sms/model/Student.java
package com.sms.model;
public class Student {
private int id;
private String studentId;
private String name;
private String gender;
private int age;
private String major;
private String className;
private String phone;
private String address;
// 构造方法、Getter和Setter省略...
// 建议使用 Lombok 插件简化代码
}
StudentDAO.java (数据访问对象):
// src/main/java/com/sms/model/StudentDAO.java
package com.sms.model;
import com.sms.util.DBUtil;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class StudentDAO {
// 添加学生
public boolean addStudent(Student student) {
String sql = "INSERT INTO student (student_id, name, gender, age, major, class_name, phone, address) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, student.getStudentId());
pstmt.setString(2, student.getName());
pstmt.setString(3, student.getGender());
pstmt.setInt(4, student.getAge());
pstmt.setString(5, student.getMajor());
pstmt.setString(6, student.getClassName());
pstmt.setString(7, student.getPhone());
pstmt.setString(8, student.getAddress());
return pstmt.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.closeAll(conn, pstmt, null);
}
return false;
}
// 根据学号删除学生
public boolean deleteStudent(String studentId) {
String sql = "DELETE FROM student WHERE student_id = ?";
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, studentId);
return pstmt.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.closeAll(conn, pstmt, null);
}
return false;
}
// 更新学生信息
public boolean updateStudent(Student student) {
String sql = "UPDATE student SET name=?, gender=?, age=?, major=?, class_name=?, phone=?, address=? WHERE student_id=?";
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(sql);
// 设置参数...
pstmt.setString(1, student.getName());
// ...其他参数
pstmt.setString(8, student.getStudentId()); // WHERE条件在最后
return pstmt.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.closeAll(conn, pstmt, null);
}
return false;
}
// 根据学号查询学生
public Student getStudentById(String studentId) {
String sql = "SELECT * FROM student WHERE student_id = ?";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
Student student = null;
try {
conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, studentId);
rs = pstmt.executeQuery();
if (rs.next()) {
student = new Student();
student.setId(rs.getInt("id"));
student.setStudentId(rs.getString("student_id"));
// ...其他属性赋值
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.closeAll(conn, pstmt, rs);
}
return student;
}
// 查询所有学生 (或按条件查询)
public List<Student> getAllStudents(String name, String major) {
List<Student> students = new ArrayList<>();
// 动态构建SQL,实现多条件查询
StringBuilder sql = new StringBuilder("SELECT * FROM student WHERE 1=1");
if (name != null && !name.trim().isEmpty()) {
sql.append(" AND name LIKE ?");
}
if (major != null && !major.trim().isEmpty()) {
sql.append(" AND major LIKE ?");
}
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(sql.toString());
int index = 1;
if (name != null && !name.trim().isEmpty()) {
pstmt.setString(index++, "%" + name + "%");
}
if (major != null && !major.trim().isEmpty()) {
pstmt.setString(index++, "%" + major + "%");
}
rs = pstmt.executeQuery();
while (rs.next()) {
Student student = new Student();
student.setId(rs.getInt("id"));
student.setStudentId(rs.getString("student_id"));
// ...其他属性赋值
students.add(student);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.closeAll(conn, pstmt, rs);
}
return students;
}
}
3 视图层 LoginView.java 和 MainView.java
LoginView.java (登录界面):
// src/main/java/com/sms/view/LoginView.java
package com.sms.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class LoginView extends JFrame {
private JTextField usernameField;
private JPasswordField passwordField;
public LoginView() {
setTitle("学生信息管理系统 - 登录");
setSize(400, 250);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null); // 居中显示
// 使用面板来组织组件
JPanel panel = new JPanel(new GridLayout(3, 2, 10, 10));
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
panel.add(new JLabel("用户名:"));
usernameField = new JTextField();
panel.add(usernameField);
panel.add(new JLabel("密 码:"));
passwordField = new JPasswordField();
panel.add(passwordField);
JButton loginButton = new JButton("登录");
JButton exitButton = new JButton("退出");
// 登录按钮事件处理
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String username = usernameField.getText();
String password = new String(passwordField.getPassword());
// TODO: 调用Controller进行验证
// 这里简单硬编码一个验证逻辑
if ("admin".equals(username) && "123456".equals(password)) {
JOptionPane.showMessageDialog(LoginView.this, "登录成功!", "提示", JOptionPane.INFORMATION_MESSAGE);
// 登录成功后,打开主界面并关闭登录界面
MainView mainView = new MainView();
mainView.setVisible(true);
LoginView.this.dispose();
} else {
JOptionPane.showMessageDialog(LoginView.this, "用户名或密码错误!", "错误", JOptionPane.ERROR_MESSAGE);
}
}
});
exitButton.addActionListener(e -> System.exit(0));
JPanel buttonPanel = new JPanel();
buttonPanel.add(loginButton);
buttonPanel.add(exitButton);
add(panel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
}
}
MainView.java (主界面):
// src/main/java/com/sms/view/MainView.java
package com.sms.view;
import com.sms.controller.MainController;
import com.sms.model.Student;
import com.sms.model.StudentDAO;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
public class MainView extends JFrame {
private JTable studentTable;
private DefaultTableModel tableModel;
private JTextField searchField;
private JComboBox<String> searchComboBox;
public MainView() {
setTitle("学生信息管理系统");
setSize(900, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// 1. 创建菜单栏
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("文件");
JMenuItem exitItem = new JMenuItem("退出");
exitItem.addActionListener(e -> System.exit(0));
fileMenu.add(exitItem);
JMenu editMenu = new JMenu("编辑");
JMenuItem addItem = new JMenuItem("添加学生");
JMenuItem updateItem = new JMenuItem("修改学生");
JMenuItem deleteItem = new JMenuItem("删除学生");
// TODO: 将菜单项与控制器关联
// addItem.addActionListener(new MainController(this, "add"));
// updateItem.addActionListener(new MainController(this, "update"));
// deleteItem.addActionListener(new MainController(this, "delete"));
editMenu.add(addItem);
editMenu.add(updateItem);
editMenu.addSeparator();
editMenu.add(deleteItem);
JMenu helpMenu = new JMenu("帮助");
JMenuItem aboutItem = new JMenuItem("quot;);
aboutItem.addActionListener(e -> {
AboutView aboutView = new AboutView();
aboutView.setVisible(true);
});
helpMenu.add(aboutItem);
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(helpMenu);
setJMenuBar(menuBar);
// 2. 创建工具栏 (查询区域)
JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
searchComboBox = new JComboBox<>(new String[]{"按学号", "按姓名", "按专业"});
searchField = new JTextField(20);
JButton searchButton = new JButton("查询");
searchButton.addActionListener(e -> {
// TODO: 调用Controller处理查询逻辑
String searchText = searchField.getText();
String searchType = (String) searchComboBox.getSelectedItem();
// ... 根据类型和文本查询数据库并刷新表格
refreshTableData(); // 示例:刷新表格
});
searchPanel.add(new JLabel("查询条件:"));
searchPanel.add(searchComboBox);
searchPanel.add(searchField);
searchPanel.add(searchButton);
// 3. 创建表格
String[] columnNames = {"学号", "姓名", "性别", "年龄", "专业", "班级"};
tableModel = new DefaultTableModel(columnNames, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return false; // 表格单元格不可编辑
}
};
studentTable = new JTable(tableModel);
JScrollPane scrollPane = new JScrollPane(studentTable);
// 4. 布局
add(searchPanel, BorderLayout.NORTH);
add(scrollPane, BorderLayout.CENTER);
// 初始化时加载数据
refreshTableData();
}
// 刷新表格数据的方法
public void refreshTableData() {
// 清空现有数据
tableModel.setRowCount(0);
// TODO: 从数据库获取数据并填充到表格
// StudentDAO dao = new StudentDAO();
// List<Student> students = dao.getAllStudents("", "");
// for (Student s : students) {
// Object[] rowData = {s.getStudentId(), s.getName(), s.getGender(), s.getAge(), s.getMajor(), s.getClassName()};
// tableModel.addRow(rowData);
// }
// 临时模拟数据
tableModel.addRow(new Object[]{"2025001", "张三", "男", 20, "计算机科学", "计科2301"});
tableModel.addRow(new Object[]{"2025002", "李四", "女", 19, "软件工程", "软工2302"});
}
}
4 控制器层 MainController.java
控制器是连接视图和模型的桥梁。
// src/main/java/com/sms/controller/MainController.java
package com.sms.controller;
import com.sms.model.Student;
import com.sms.model.StudentDAO;
import com.sms.view.AddStudentView;
import com.sms.view.MainView;
import com.sms.view.UpdateStudentView;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
public class MainController implements ActionListener {
private MainView mainView;
private StudentDAO studentDAO;
public MainController(MainView mainView) {
this.mainView = mainView;
this.studentDAO = new StudentDAO();
}
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
switch (command) {
case "add":
// 打开添加学生窗口
AddStudentView addView = new AddStudentView(mainView);
addView.setVisible(true);
break;
case "update":
// 获取选中的行
int selectedRow = mainView.getStudentTable().getSelectedRow();
if (selectedRow == -1) {
JOptionPane.showMessageDialog(mainView, "请先选择要修改的学生!", "提示", JOptionPane.WARNING_MESSAGE);
return;
}
String studentIdToUpdate = (String) mainView.getTableModel().getValueAt(selectedRow, 0);
// 从数据库获取该学生完整信息
Student studentToUpdate = studentDAO.getStudentById(studentIdToUpdate);
// 打开修改学生窗口并传入学生信息
UpdateStudentView updateView = new UpdateStudentView(mainView, studentToUpdate);
updateView.setVisible(true);
break;
case "delete":
int selectedRowForDelete = mainView.getStudentTable().getSelectedRow();
if (selectedRowForDelete == -1) {
JOptionPane.showMessageDialog(mainView, "请先选择要删除的学生!", "提示", JOptionPane.WARNING_MESSAGE);
return;
}
int confirm = JOptionPane.showConfirmDialog(mainView, "确定要删除选中的学生吗?", "确认删除", JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
String studentIdToDelete = (String) mainView.getTableModel().getValueAt(selectedRowForDelete, 0);
if (studentDAO.deleteStudent(studentIdToDelete)) {
JOptionPane.showMessageDialog(mainView, "删除成功!", "成功", JOptionPane.INFORMATION_MESSAGE);
mainView.refreshTableData(); // 刷新表格
} else {
JOptionPane.showMessageDialog(mainView, "删除失败!", "错误", JOptionPane.ERROR_MESSAGE);
}
}
break;
}
}
// 可以添加处理查询的方法
public void handleSearch(String searchText, String searchType) {
List<Student> students = studentDAO.getAllStudents(searchText, ""); // 根据实际查询逻辑调整
DefaultTableModel model = mainView.getTableModel();
model.setRowCount(0); // 清空表格
for (Student s : students) {
Object[] rowData = {s.getStudentId(), s.getName(), s.getGender(), s.getAge(), s.getMajor(), s.getClassName()};
model.addRow(rowData);
}
}
}
实现步骤总结
- 环境准备: 安装 JDK, MySQL, IntelliJ IDEA。
- 创建项目: 在 IDEA 中创建一个标准的 Java 项目。
- 配置数据库: 在 MySQL 中创建
student_db和student表。 - 添加依赖: 下载 MySQL JDBC 驱动 (
.jar文件),并将其添加到项目的lib目录,然后在 IDEA 中将其作为库引入。 - 编写代码:
- 按照项目结构,逐个创建包和类。
- 首先完成
DBUtil和db.properties,确保数据库连接正常。 - 然后编写
Student实体类和StudentDAO,使用单元测试或简单的main方法测试数据库的增删改查是否正常。 - 开发各个
View界面,先实现静态布局,事件处理可以先留空或写死。 - 编写
Controller,将View的事件和Model的业务逻辑连接起来。
- 整合与测试: 将所有模块整合,进行完整的功能测试,包括正常流程和异常流程(如输入空数据、重复学号等)。
- 打包与部署: 可以使用 IDEA 的打包功能,将项目打包成一个可执行的
.jar文件。
扩展与优化建议
如果课程设计要求更高,可以考虑以下扩展点:
- 用户管理: 增加一个管理员表,实现多用户登录和权限控制(如普通教师只能查看,管理员能增删改)。
- 数据导入/导出: 增加 Excel 导入/导出功能,方便批量处理学生数据,可以使用 Apache POI 库。
- 分页查询: 当学生数据量很大时,实现表格分页显示。
- 日志记录: 使用 Log4j 或 SLF4J 记录系统的操作日志和错误信息,便于排查问题。
- 美化界面: 使用第三方皮肤库(如 FlatLaf)来美化 Swing 界面,使其更现代化。
- 数据备份与恢复: 提供数据库备份和恢复功能。
这个设计方案为你提供了一个坚实的基础,你可以根据自己课程的具体要求进行裁剪和扩展,祝你课程设计顺利!
