项目概述
- 技术栈:
- 后端: Java 8+
- 数据库: MySQL 5.7+
- 连接技术: JDBC
- 架构模式: MVC
- 功能模块:
- 学生信息管理: 添加、删除、修改、查询学生信息。
- 学生成绩管理: 为学生添加、修改、查询成绩(我们将成绩与学生表关联)。
- 数据持久化: 所有数据存储在 MySQL 数据库中。
- 系统设计:
- Model (模型):
Student.java,Score.java(数据实体) - DAO (数据访问对象):
StudentDAO.java,ScoreDAO.java(负责与数据库交互) - Service (服务层):
StudentService.java,ScoreService.java(处理业务逻辑) - View (视图):
Main.java(控制台用户界面) - Util (工具类):
DBUtil.java(管理数据库连接)
- Model (模型):
第一步:环境准备
- 安装 JDK: 确保你的电脑上安装了 JDK 8 或更高版本,并配置好
JAVA_HOME和Path环境变量。 - 安装 MySQL: 安装 MySQL 数据库,并确保服务正在运行,创建一个数据库,
student_db。 - IDE: 使用 IntelliJ IDEA 或 Eclipse 等集成开发环境。
第二步:数据库设计与创建
在 MySQL 中创建数据库和表,我们创建两个表:students 和 scores。

-- 创建数据库
CREATE DATABASE IF NOT EXISTS student_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 使用数据库
USE student_db;
-- 创建学生表
CREATE TABLE students (
id INT PRIMARY KEY AUTO_INCREMENT,
student_no VARCHAR(20) NOT NULL UNIQUE,
name VARCHAR(50) NOT NULL,
gender VARCHAR(10),
age INT,
birth_date DATE,
class_name VARCHAR(50)
);
-- 创建成绩表
CREATE TABLE scores (
id INT PRIMARY KEY AUTO_INCREMENT,
student_id INT NOT NULL,
subject VARCHAR(50) NOT NULL,
score DECIMAL(5, 2) NOT NULL,
FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE
);
-- 插入一些测试数据
INSERT INTO students (student_no, name, gender, age, birth_date, class_name) VALUES
('2025001', '张三', '男', 20, '2003-05-15', '计算机科学与技术1班'),
('2025002', '李四', '女', 19, '2004-08-22', '软件工程1班'),
('2025003', '王五', '男', 21, '2002-11-10', '计算机科学与技术1班');
INSERT INTO scores (student_id, subject, score) VALUES
(1, '高等数学', 90.50),
(1, 'Java程序设计', 88.00),
(2, '高等数学', 92.00),
(2, '大学英语', 85.50),
(3, 'Java程序设计', 78.00),
(3, '数据结构', 91.00);
第三步:创建 Java 项目并添加依赖
- 在你的 IDE 中创建一个新的 Java 项目。
- 添加 MySQL JDBC 驱动:
- Maven (推荐): 在
pom.xml文件中添加以下依赖:<dependencies> <!-- MySQL Connector/J --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> <!-- 使用与你的MySQL版本匹配的版本 --> </dependency> </dependencies> - 手动下载: 访问 Maven Central Repository 下载
.jar文件,并将其添加到项目的库中。
- Maven (推荐): 在
第四步:项目代码实现
按照 MVC 架构,我们将代码分为几个包。
Model (模型包: com.example.model)
这些是简单的 Java Bean,用于封装数据。
Student.java
package com.example.model;
import java.util.Date;
public class Student {
private int id;
private String studentNo;
private String name;
private String gender;
private int age;
private Date birthDate;
private String className;
// 构造方法、Getter 和 Setter
public Student() {}
public Student(String studentNo, String name, String gender, int age, Date birthDate, String className) {
this.studentNo = studentNo;
this.name = name;
this.gender = gender;
this.age = age;
this.birthDate = birthDate;
this.className = className;
}
// Getters and Setters
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getStudentNo() { return studentNo; }
public void setStudentNo(String studentNo) { this.studentNo = studentNo; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getGender() { return gender; }
public void setGender(String gender) { this.gender = gender; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public Date getBirthDate() { return birthDate; }
public void setBirthDate(Date birthDate) { this.birthDate = birthDate; }
public String getClassName() { return className; }
public void setClassName(String className) { this.className = className; }
@Override
public String toString() {
return "Student{" +
"id=" + id +
", studentNo='" + studentNo + '\'' +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", birthDate=" + birthDate +
", className='" + className + '\'' +
'}';
}
}
Score.java

package com.example.model;
public class Score {
private int id;
private int studentId;
private String subject;
private double score;
// 构造方法、Getter 和 Setter
public Score() {}
public Score(int studentId, String subject, double score) {
this.studentId = studentId;
this.subject = subject;
this.score = score;
}
// Getters and Setters
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public int getStudentId() { return studentId; }
public void setStudentId(int studentId) { this.studentId = studentId; }
public String getSubject() { return subject; }
public void setSubject(String subject) { this.subject = subject; }
public double getScore() { return score; }
public void setScore(double score) { this.score = score; }
@Override
public String toString() {
return "Score{" +
"id=" + id +
", studentId=" + studentId +
", subject='" + subject + '\'' +
", score=" + score +
'}';
}
}
Util (工具包: com.example.util)
DBUtil.java - 负责管理数据库连接。
package com.example.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?useSSL=false&serverTimezone=UTC";
private static final String USER = "root"; // 你的MySQL用户名
private static final String PASSWORD = "your_password"; // 你的MySQL密码
// 静态代码块,在类加载时执行,注册驱动
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("Failed to load MySQL driver", e);
}
}
// 获取数据库连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USER, PASSWORD);
}
// 关闭资源
public static void closeConnection(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
DAO (数据访问对象包: com.example.dao)
StudentDAO.java - 处理学生数据的增删改查。
package com.example.dao;
import com.example.model.Student;
import com.example.util.DBUtil;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class StudentDAO {
// 添加学生
public void addStudent(Student student) throws SQLException {
String sql = "INSERT INTO students (student_no, name, gender, age, birth_date, class_name) VALUES (?, ?, ?, ?, ?, ?)";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, student.getStudentNo());
pstmt.setString(2, student.getName());
pstmt.setString(3, student.getGender());
pstmt.setInt(4, student.getAge());
pstmt.setDate(5, new java.sql.Date(student.getBirthDate().getTime()));
pstmt.setString(6, student.getClassName());
pstmt.executeUpdate();
}
}
// 删除学生 (根据ID)
public void deleteStudent(int id) throws SQLException {
String sql = "DELETE FROM students WHERE id = ?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
pstmt.executeUpdate();
}
}
// 更新学生信息
public void updateStudent(Student student) throws SQLException {
String sql = "UPDATE students SET student_no = ?, name = ?, gender = ?, age = ?, birth_date = ?, class_name = ? WHERE id = ?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, student.getStudentNo());
pstmt.setString(2, student.getName());
pstmt.setString(3, student.getGender());
pstmt.setInt(4, student.getAge());
pstmt.setDate(5, new java.sql.Date(student.getBirthDate().getTime()));
pstmt.setString(6, student.getClassName());
pstmt.setInt(7, student.getId());
pstmt.executeUpdate();
}
}
// 查询所有学生
public List<Student> getAllStudents() throws SQLException {
List<Student> students = new ArrayList<>();
String sql = "SELECT * FROM students";
try (Connection conn = DBUtil.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
Student student = new Student();
student.setId(rs.getInt("id"));
student.setStudentNo(rs.getString("student_no"));
student.setName(rs.getString("name"));
student.setGender(rs.getString("gender"));
student.setAge(rs.getInt("age"));
student.setBirthDate(rs.getDate("birth_date"));
student.setClassName(rs.getString("class_name"));
students.add(student);
}
}
return students;
}
// 根据ID查询学生
public Student getStudentById(int id) throws SQLException {
String sql = "SELECT * FROM students WHERE id = ?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
Student student = new Student();
student.setId(rs.getInt("id"));
student.setStudentNo(rs.getString("student_no"));
student.setName(rs.getString("name"));
student.setGender(rs.getString("gender"));
student.setAge(rs.getInt("age"));
student.setBirthDate(rs.getDate("birth_date"));
student.setClassName(rs.getString("class_name"));
return student;
}
}
}
return null;
}
}
ScoreDAO.java - 处理成绩数据的增删改查。
package com.example.dao;
import com.example.model.Score;
import com.example.util.DBUtil;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class ScoreDAO {
// 添加成绩
public void addScore(Score score) throws SQLException {
String sql = "INSERT INTO scores (student_id, subject, score) VALUES (?, ?, ?)";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, score.getStudentId());
pstmt.setString(2, score.getSubject());
pstmt.setDouble(3, score.getScore());
pstmt.executeUpdate();
}
}
// 更新成绩
public void updateScore(Score score) throws SQLException {
String sql = "UPDATE scores SET subject = ?, score = ? WHERE id = ?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, score.getSubject());
pstmt.setDouble(2, score.getScore());
pstmt.setInt(3, score.getId());
pstmt.executeUpdate();
}
}
// 删除成绩 (根据ID)
public void deleteScore(int id) throws SQLException {
String sql = "DELETE FROM scores WHERE id = ?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
pstmt.executeUpdate();
}
}
// 查询某学生的所有成绩
public List<Score> getScoresByStudentId(int studentId) throws SQLException {
List<Score> scores = new ArrayList<>();
String sql = "SELECT * FROM scores WHERE student_id = ?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, studentId);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
Score score = new Score();
score.setId(rs.getInt("id"));
score.setStudentId(rs.getInt("student_id"));
score.setSubject(rs.getString("subject"));
score.setScore(rs.getDouble("score"));
scores.add(score);
}
}
}
return scores;
}
}
Service (服务层包: com.example.service)
StudentService.java - 处理与学生相关的业务逻辑。
package com.example.service;
import com.example.dao.StudentDAO;
import com.example.model.Student;
import java.sql.SQLException;
import java.util.List;
public class StudentService {
private StudentDAO studentDAO = new StudentDAO();
public void addStudent(Student student) throws SQLException {
studentDAO.addStudent(student);
}
public void deleteStudent(int id) throws SQLException {
studentDAO.deleteStudent(id);
}
public void updateStudent(Student student) throws SQLException {
studentDAO.updateStudent(student);
}
public List<Student> getAllStudents() throws SQLException {
return studentDAO.getAllStudents();
}
public Student getStudentById(int id) throws SQLException {
return studentDAO.getStudentById(id);
}
}
ScoreService.java - 处理与成绩相关的业务逻辑。
package com.example.service;
import com.example.dao.ScoreDAO;
import com.example.model.Score;
import java.sql.SQLException;
import java.util.List;
public class ScoreService {
private ScoreDAO scoreDAO = new ScoreDAO();
public void addScore(Score score) throws SQLException {
scoreDAO.addScore(score);
}
public void updateScore(Score score) throws SQLException {
scoreDAO.updateScore(score);
}
public void deleteScore(int id) throws SQLException {
scoreDAO.deleteScore(id);
}
public List<Score> getScoresByStudentId(int studentId) throws SQLException {
return scoreDAO.getScoresByStudentId(studentId);
}
}
View (视图包: com.example.view)
Main.java - 程序入口和用户交互界面。
package com.example.view;
import com.example.model.Student;
import com.example.model.Score;
import com.example.service.ScoreService;
import com.example.service.StudentService;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
public class Main {
private static StudentService studentService = new StudentService();
private static ScoreService scoreService = new ScoreService();
private static Scanner scanner = new Scanner(System.in);
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public static void main(String[] args) {
while (true) {
showMenu();
int choice = scanner.nextInt();
scanner.nextLine(); // 消费换行符
try {
switch (choice) {
case 1:
listAllStudents();
break;
case 2:
addStudent();
break;
case 3:
updateStudent();
break;
case 4:
deleteStudent();
break;
case 5:
manageScores();
break;
case 0:
System.out.println("感谢使用,再见!");
scanner.close();
System.exit(0);
default:
System.out.println("无效的输入,请重新选择!");
}
} catch (SQLException | ParseException e) {
System.err.println("操作失败: " + e.getMessage());
}
}
}
private static void showMenu() {
System.out.println("\n========== 学生管理系统 ==========");
System.out.println("1. 查看所有学生");
System.out.println("2. 添加学生");
System.out.println("3. 修改学生信息");
System.out.println("4. 删除学生");
System.out.println("5. 成绩管理");
System.out.println("0. 退出系统");
System.out.println("=================================");
System.out.print("请输入您的选择: ");
}
private static void listAllStudents() throws SQLException {
System.out.println("\n--- 所有学生列表 ---");
List<Student> students = studentService.getAllStudents();
if (students.isEmpty()) {
System.out.println("当前没有学生信息。");
} else {
for (Student s : students) {
System.out.println(s);
}
}
}
private static void addStudent() throws ParseException, SQLException {
System.out.println("\n--- 添加新学生 ---");
System.out.print("学号: ");
String studentNo = scanner.nextLine();
System.out.print("姓名: ");
String name = scanner.nextLine();
System.out.print("性别: ");
String gender = scanner.nextLine();
System.out.print("年龄: ");
int age = scanner.nextInt();
scanner.nextLine(); // 消费换行符
System.out.print("出生日期 (yyyy-MM-dd): ");
Date birthDate = sdf.parse(scanner.nextLine());
System.out.print("班级: ");
String className = scanner.nextLine();
Student student = new Student(studentNo, name, gender, age, birthDate, className);
studentService.addStudent(student);
System.out.println("学生添加成功!");
}
private static void updateStudent() throws ParseException, SQLException {
System.out.println("\n--- 修改学生信息 ---");
System.out.print("请输入要修改的学生ID: ");
int id = scanner.nextInt();
scanner.nextLine(); // 消费换行符
Student student = studentService.getStudentById(id);
if (student == null) {
System.out.println("未找到ID为 " + id + " 的学生。");
return;
}
System.out.println("当前信息: " + student);
System.out.println("请输入新信息 (不修改则直接回车):");
System.out.print("姓名 [" + student.getName() + "]: ");
String name = scanner.nextLine();
if (!name.isEmpty()) student.setName(name);
System.out.print("性别 [" + student.getGender() + "]: ");
String gender = scanner.nextLine();
if (!gender.isEmpty()) student.setGender(gender);
System.out.print("年龄 [" + student.getAge() + "]: ");
String ageStr = scanner.nextLine();
if (!ageStr.isEmpty()) student.setAge(Integer.parseInt(ageStr));
System.out.print("出生日期 [" + sdf.format(student.getBirthDate()) + "] (yyyy-MM-dd): ");
String birthDateStr = scanner.nextLine();
if (!birthDateStr.isEmpty()) student.setBirthDate(sdf.parse(birthDateStr));
System.out.print("班级 [" + student.getClassName() + "]: ");
String className = scanner.nextLine();
if (!className.isEmpty()) student.setClassName(className);
studentService.updateStudent(student);
System.out.println("学生信息更新成功!");
}
private static void deleteStudent() throws SQLException {
System.out.println("\n--- 删除学生 ---");
System.out.print("请输入要删除的学生ID: ");
int id = scanner.nextInt();
scanner.nextLine(); // 消费换行符
Student student = studentService.getStudentById(id);
if (student == null) {
System.out.println("未找到ID为 " + id + " 的学生。");
return;
}
System.out.println("您确定要删除学生 " + student.getName() + " (ID: " + id + ") 吗? (y/n)");
String confirm = scanner.nextLine();
if ("y".equalsIgnoreCase(confirm)) {
studentService.deleteStudent(id);
System.out.println("学生删除成功!");
} else {
System.out.println("删除操作已取消。");
}
}
private static void manageScores() throws SQLException {
System.out.println("\n--- 成绩管理 ---");
System.out.print("请输入学生ID: ");
int studentId = scanner.nextInt();
scanner.nextLine(); // 消费换行符
Student student = studentService.getStudentById(studentId);
if (student == null) {
System.out.println("未找到ID为 " + studentId + " 的学生。");
return;
}
System.out.println("正在管理学生 " + student.getName() + " 的成绩:");
List<Score> scores = scoreService.getScoresByStudentId(studentId);
if (scores.isEmpty()) {
System.out.println("该学生暂无成绩记录。");
} else {
for (Score s : scores) {
System.out.println(s);
}
}
System.out.println("\n1. 添加成绩");
System.out.println("2. 修改成绩");
System.out.println("3. 删除成绩");
System.out.println("0. 返回主菜单");
System.out.print("请选择: ");
int scoreChoice = scanner.nextInt();
scanner.nextLine(); // 消费换行符
switch (scoreChoice) {
case 1:
System.out.print("科目: ");
String subject = scanner.nextLine();
System.out.print("分数: ");
double scoreValue = scanner.nextDouble();
scanner.nextLine(); // 消费换行符
Score newScore = new Score(studentId, subject, scoreValue);
scoreService.addScore(newScore);
System.out.println("成绩添加成功!");
break;
case 2:
// 修改成绩逻辑 (略,类似updateStudent)
System.out.println("修改成绩功能待实现。");
break;
case 3:
System.out.print("请输入要删除的成绩ID: ");
int scoreId = scanner.nextInt();
scanner.nextLine();
scoreService.deleteScore(scoreId);
System.out.println("成绩删除成功!");
break;
case 0:
return;
default:
System.out.println("无效的输入。");
}
}
}
第五步:运行项目
- 确保你的 MySQL 服务正在运行,并且数据库和表已按上面的脚本创建。
- 修改
DBUtil.java中的USER和PASSWORD为你自己的 MySQL 用户名和密码。 - 运行
Main.java文件。 - 现在你应该能看到一个控制台菜单,可以通过输入数字来操作学生管理系统了。
总结与展望
这个学生管理系统是一个典型的入门级 Java Web 项目原型,它完整地展示了如何使用 Java 和 JDBC 进行数据库操作。
优点:
- 结构清晰: MVC 架构使得代码职责分明,易于维护和扩展。
- 功能完整: 实现了基本的 CRUD (增删改查) 操作。
- 实践性强: 涵盖了数据库设计、JDBC 编程、异常处理、用户交互等多个方面。
可以进一步改进的方向:
- 使用连接池: 在
DBUtil中引入如 HikariCP、Druid 等数据库连接池,以提高数据库连接性能和稳定性。 - 引入日志框架: 使用 SLF4J + Logback 等日志框架替代
System.out.println,便于日志管理和问题追踪。 - 引入 ORM 框架: 使用 MyBatis 或 Hibernate 等 ORM (Object-Relational Mapping) 框架,可以简化数据库操作,将 SQL 语句与 Java 代码更好地解耦。
- 图形用户界面: 使用 JavaFX、Swing 或开发一个 Web 界面(如 Spring Boot + Thymeleaf),替代控制台交互,提升用户体验。
- 增加更多功能: 如按条件查询学生、统计学生平均分、实现分页查询等。
