需求分析与设计
明确项目目标和功能需求,设计系统架构和模块划分
学习目标
完成学生管理系统的需求文档和架构设计图
核心功能需求
- 学生信息管理(增删改查)
- 班级管理(创建、修改、删除)
- 成绩录入与统计分析
- 用户权限管理(管理员、教师、学生)
- 数据导出功能(Excel格式)
系统架构设计
- 三层架构设计:表现层、业务层、数据层
- MVC模式:模型-视图-控制器分离
- 使用Spring Boot框架简化开发
- MySQL作为数据库存储
表现层
Swing/控制台界面
业务层
Service组件
数据层
DAO组件
数据库
MySQL
设计要点
在设计阶段,要特别注意模块之间的解耦。例如,数据访问层(DAO)应该完全独立于业务逻辑层(Service),这样当需要更换数据库时(如从MySQL迁移到PostgreSQL),只需修改DAO实现而不影响业务逻辑。
常见错误
1. 需求不明确导致后期频繁变更
2. 模块职责划分不清,导致代码耦合度高
3. 未考虑扩展性,导致系统难以维护
数据库设计与实现
设计数据库表结构,创建数据库和表,建立表关系
学习目标
完成学生管理系统数据库设计,创建所有表结构
关键数据表设计
- 学生表(student):id, 姓名, 性别, 出生日期, 班级ID
- 班级表(class):id, 班级名称, 班主任, 创建时间
- 成绩表(score):id, 学生ID, 课程, 分数, 考试时间
- 用户表(user):id, 用户名, 密码, 角色
表关系设计
- 一个班级有多个学生(1:N)
- 一个学生有多条成绩记录(1:N)
- 用户表独立,通过角色控制权限
创建学生表SQL示例
CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, gender ENUM('男', '女') NOT NULL, birth_date DATE NOT NULL, class_id INT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (class_id) REFERENCES class(id) ON DELETE CASCADE );
数据库优化
1. 为经常查询的字段添加索引(如学生姓名、班级ID)
2. 使用InnoDB引擎支持事务和外键
3. 合理设置字段类型和长度,避免空间浪费
实践任务
- 创建班级表、成绩表和用户表
- 为各表添加外键约束
- 插入测试数据(至少5个班级,30名学生)
数据访问层开发(DAO)
实现数据库操作接口,封装CRUD方法
学习目标
完成所有数据实体的DAO接口和实现类
DAO接口设计
- 为每个实体创建DAO接口
- 定义CRUD基本操作方法
- 添加必要的查询方法
实现技术选择
- Spring Data JPA(推荐)
- MyBatis(灵活SQL)
- JDBC Template(简单场景)
使用Spring Data JPA的DAO示例
public interface StudentRepository extends JpaRepository<Student, Long> { // 根据姓名查询学生 List<Student> findByName(String name); // 根据班级ID查询学生 List<Student> findByClassId(Long classId); // 根据姓名模糊查询 List<Student> findByNameContaining(String keyword); }
常见错误
1. SQL注入风险(使用预编译语句解决)
2. 事务管理不当(使用@Transactional注解)
3. N+1查询问题(使用JOIN FETCH优化)
4. 连接泄漏(使用try-with-resources)
DAO层最佳实践
1. 每个DAO方法应只完成一个数据库操作
2. 使用Optional处理可能为空的结果
3. 批量操作使用JPA的saveAll()方法
4. 复杂查询使用@Query注解编写JPQL
业务逻辑层开发(Service)
实现业务规则和处理流程,协调多个DAO操作
学习目标
完成学生管理系统的核心业务逻辑实现
服务接口设计
- 为每个业务实体创建Service接口
- 定义业务方法(如添加学生、计算平均分)
- 接口与实现分离,便于测试和扩展
事务管理
- 使用@Transactional注解管理事务
- 设置合适的事务传播行为
- 处理并发和锁机制
学生服务实现示例
@Service public class StudentServiceImpl implements StudentService { @Autowired private StudentRepository studentRepository; @Autowired private ClassService classService; @Override @Transactional public Student addStudent(Student student) { // 检查班级是否存在 if (!classService.existsById(student.getClassId())) { throw new IllegalArgumentException("班级不存在"); } // 保存学生信息 return studentRepository.save(student); } @Override public double calculateAverageScore(Long studentId) { List<Score> scores = scoreRepository.findByStudentId(studentId); if (scores.isEmpty()) { return 0.0; } double sum = scores.stream() .mapToDouble(Score::getValue) .sum(); return sum / scores.size(); } }
业务层设计原则
1. 单一职责原则:每个Service只处理单一业务
2. 依赖倒置原则:依赖接口而不是具体实现
3. 开闭原则:对扩展开放,对修改关闭
4. 使用DTO在不同层之间传输数据
实践任务
- 实现学生添加、更新和删除业务逻辑
- 编写班级学生统计方法
- 实现成绩分析服务(最高分、最低分、平均分)
用户界面开发
实现控制台或Swing图形界面,与用户交互
学习目标
完成学生管理系统的用户界面,实现基本功能
控制台界面
- 简单易实现,适合初期开发
- 使用Scanner接收用户输入
- 通过命令行菜单导航
Swing图形界面
- 提供更好的用户体验
- 使用JFrame、JPanel等组件
- 结合MVC模式分离界面和逻辑
控制台主菜单示例
public class ConsoleUI { private Scanner scanner = new Scanner(System.in); private StudentService studentService; public void start() { while (true) { System.out.println("\n==== 学生管理系统 ===="); System.out.println("1. 添加学生"); System.out.println("2. 查询学生"); System.out.println("3. 删除学生"); System.out.println("4. 退出系统"); System.out.print("请选择操作: "); int choice = scanner.nextInt(); scanner.nextLine(); // 消耗换行符 switch (choice) { case 1: addStudent(); break; case 2: searchStudents(); break; case 3: deleteStudent(); break; case 4: System.out.println("感谢使用,再见!"); return; default: System.out.println("无效选择,请重新输入"); } } } private void addStudent() { // 实现添加学生逻辑 } // 其他方法实现... }
界面开发建议
1. 保持界面与业务逻辑分离
2. 为Swing界面使用单独的线程(SwingUtilities.invokeLater)
3. 使用数据绑定简化界面更新
4. 为耗时操作添加进度指示器
界面层常见错误
1. 在事件调度线程(EDT)中执行耗时操作导致界面卡顿
2. 未进行输入验证,导致异常或数据不一致
3. 界面组件命名混乱,难以维护
4. 缺乏国际化支持
项目部署
将应用程序部署到服务器或生成可执行文件
学习目标
掌握Spring Boot应用的多种部署方式
生成可执行JAR
使用Maven或Gradle打包项目:
# Maven 打包命令 mvn clean package # 生成的可执行JAR位于target目录 java -jar student-management.jar
Docker容器化部署
创建Dockerfile构建镜像:
# Dockerfile 示例
FROM openjdk:17-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
构建并运行容器:
docker build -t student-app . docker run -p 8080:8080 student-app
部署到Tomcat服务器
1. 修改pom.xml设置打包方式为war
2. 排除内嵌Tomcat依赖
3. 实现SpringBootServletInitializer
4. 打包部署到外部Tomcat
部署检查清单
- 确保数据库连接配置正确
- 设置合适的JVM内存参数
- 配置生产环境日志级别
- 添加健康检查端点
- 设置安全防护(如CSRF、XSS)
周末测试
全面测试系统功能,验证项目开发成果
学习目标
完成学生管理系统的功能测试和性能测试
功能测试用例
测试项 | 测试步骤 | 预期结果 |
---|---|---|
添加学生 | 输入有效学生信息并提交 | 学生信息正确保存到数据库 |
查询学生 | 按姓名或班级查询 | 返回正确学生列表 |
删除学生 | 选择学生并删除 | 学生信息从数据库移除 |
成绩统计 | 为多个学生添加成绩 | 计算并显示正确的平均分 |
性能测试要点
并发测试
- 使用JMeter模拟多用户
- 测试50并发下的响应时间
- 监控系统资源使用情况
压力测试
- 逐步增加负载至系统崩溃点
- 记录最大吞吐量
- 识别系统瓶颈
稳定性测试
- 持续运行系统24小时
- 监控内存泄漏情况
- 检查日志是否有错误
测试常见问题
1. 边界条件未充分测试(如空列表、最大长度)
2. 未模拟异常场景(如数据库连接失败)
3. 缺乏自动化测试,回归测试效率低
4. 性能测试环境与生产环境差异大
测试改进建议
1. 使用JUnit编写单元测试,确保核心逻辑正确
2. 使用Mockito模拟依赖组件
3. 集成测试使用Testcontainers创建真实数据库环境
4. 使用JaCoCo检查测试覆盖率