# sims **Repository Path**: draco189_admin/sims ## Basic Information - **Project Name**: sims - **Description**: 学生信息管理系统(SIMS)是一个基于控制台的学生信息管理应用,专为Java初学者设计。本项目不仅是《Java项目开发工作手册》的配套教学代码示例,更是帮助学习者从基础语法过渡到企业级项目开发的重要桥梁。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-11 - **Last Updated**: 2026-06-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 学生信息管理系统 (SIMS) - Java三层架构实战项目 ## 📚 项目简介 本项目是一个基于**控制台的学生信息管理系统**(Student Information Management System),专为**Java初学者**设计,用于学习: - ✅ **Java三层架构**(Controller-Service-DAO)的设计思想 - ✅ **面向接口编程**与**依赖注入**的实践 - ✅ **异常处理机制**的最佳实践 - ✅ **Maven工程化开发**流程 - ✅ **单元测试**编写方法 > 💡 **适用人群**:已完成Java基础语法学习,准备进入企业级项目开发学习的初学者 > 👨‍🏫 **配套资源**:本项目是《Java项目开发工作手册》的配套代码示例 --- ## 🎯 学习目标 通过本项目,你将掌握: ### 1. 三层架构设计 - **表现层(Controller)**:处理用户交互和输入输出 - **业务层(Service)**:实现业务逻辑和事务控制 - **数据访问层(DAO)**:封装数据持久化操作 ### 2. 核心编程思想 - **面向接口编程**:各层之间通过接口通信,降低耦合 - **依赖注入(DI)**:手动实现依赖注入,理解Spring IOC原理 - **单一职责原则**:每层只负责自己的职责 ### 3. 工程化开发 - Maven项目结构规范 - 依赖管理与版本控制 - 单元测试编写(JUnit 5 + Mockito) - 自定义异常体系设计 --- ## 🛠️ 技术栈 | 技术 | 版本 | 用途 | |------|------|------| | Java | 17 | 核心开发语言 | | Maven | 3.x | 项目构建与依赖管理 | | JUnit 5 | 5.9.2 | 单元测试框架 | | Mockito | 5.3.1 | Mock测试框架 | --- ## 📂 项目结构 ``` sims/ ├── src/ │ ├── main/java/net/zjitc/sims/ │ │ ├── controller/ # 【表现层】控制器 │ │ │ └── StudentController.java # 学生管理控制器 │ │ ├── service/ # 【业务层】服务 │ │ │ ├── StudentService.java # 服务接口 │ │ │ └── StudentServiceImpl.java # 服务实现 │ │ ├── dao/ # 【数据层】数据访问对象 │ │ │ ├── StudentDAO.java # DAO接口 │ │ │ └── StudentDAOImpl.java # DAO实现(内存存储) │ │ ├── model/ # 【实体层】数据模型 │ │ │ └── Student.java # 学生实体类 │ │ ├── exception/ # 【异常层】自定义异常 │ │ │ ├── DuplicateStudentException.java # 重复学生异常 │ │ │ ├── StudentNotFoundException.java # 学生不存在异常 │ │ │ └── StudentException.java # 学生异常基类 │ │ ├── util/ # 【工具层】工具类 │ │ │ └── InputUtil.java # 输入验证工具 │ │ └── Main.java # 程序入口(依赖注入组装) │ │ │ └── test/java/net/zjitc/sims/ │ ├── dao/ │ │ └── StudentDAOImplTest.java # DAO层单元测试 │ └── service/ │ └── StudentServiceImplTest.java # Service层单元测试 │ ├── pom.xml # Maven配置文件 └── ReadMe.md # 项目说明文档 ``` --- ## 🚀 快速开始 ### 环境要求 - JDK 17 或更高版本 - Maven 3.6+ - IDE推荐:IntelliJ IDEA / Eclipse ### 运行项目 #### 方式一:使用Maven命令 ```bash # 编译项目 mvn clean compile # 运行程序 mvn exec:java ``` #### 方式二:使用IDE 1. 用IDEA打开项目 2. 等待Maven依赖下载完成 3. 运行 `Main.java` 中的 `main` 方法 ### 功能演示 启动后,你将看到以下菜单: ``` ======================================== 欢迎使用学生信息管理系统 (SIMS) v1.0 ======================================== 1. 添加学生 2. 删除学生 3. 修改学生 4. 查询学生(按姓名) 5. 列出所有学生 6. 退出系统 请选择操作 (1-6): ``` --- ## 🏗️ 架构设计详解 ### 1. 三层架构图 ``` ┌─────────────────────────────────────┐ │ Controller 层 │ │ (StudentController) │ │ - 接收用户输入 │ │ - 调用Service处理业务 │ │ - 展示结果给用户 │ └──────────────┬──────────────────────┘ │ 依赖 ┌──────────────▼──────────────────────┐ │ Service 层 │ │ (StudentService + Impl) │ │ - 业务逻辑处理 │ │ - 事务控制 │ │ - 异常转换 │ └──────────────┬──────────────────────┘ │ 依赖 ┌──────────────▼──────────────────────┐ │ DAO 层 │ │ (StudentDAO + Impl) │ │ - 数据增删改查 │ │ - 数据存储细节封装 │ └─────────────────────────────────────┘ ``` ### 2. 依赖注入示例 在 [Main.java](file:///D:/java/sims/src/main/java/net/zjitc/sims/Main.java) 中,我们手动实现了依赖注入: ```java // 第一层:创建 DAO(数据层) StudentDAO studentDao = new StudentDAOImpl(); // 第二层:创建 Service(业务层),注入 DAO StudentService studentService = new StudentServiceImpl(studentDao); // 第三层:创建 Controller(交互层),注入 Service StudentController controller = new StudentController(studentService); // 启动系统 controller.start(); ``` > 💡 **思考题**:如果将来要将数据存储从 `HashMap` 改为数据库,需要修改哪些代码? > **答案**:只需修改 `Main.java` 中的一行:`StudentDAO studentDao = new JdbcStudentDAOImpl();` > 这就是**面向接口编程**的优势! ### 3. 异常处理体系 ``` StudentException (自定义异常基类) ├── DuplicateStudentException # 添加学生时学号重复 └── StudentNotFoundException # 查询/删除/修改时学生不存在 ``` **异常处理策略**: - **DAO层**:返回 `boolean` 或 `null`,不抛异常 - **Service层**:转换为受检异常(Checked Exception),强制调用方处理 - **Controller层**:捕获异常,给出友好的用户提示 --- ## 📝 核心代码解析 ### 1. 实体类设计 [Student.java](file:///D:/java/sims/src/main/java/net/zjitc/sims/model/Student.java) 重写了 `equals()` 和 `hashCode()`: ```java @Override public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return Objects.equals(id, student.id); // 学号相同即为同一学生 } @Override public int hashCode() { return Objects.hashCode(id); } ``` > ⚠️ **重要**:在使用 `HashMap` 存储时,必须正确重写这两个方法! ### 2. 接口设计规范 **DAO接口** ([StudentDAO.java](file:///D:/java/sims/src/main/java/net/zjitc/sims/dao/StudentDAO.java)): - 返回值多为 `boolean` 或具体对象 - 不抛异常,由上层决定如何处理 **Service接口** ([StudentService.java](file:///D:/java/sims/src/main/java/net/zjitc/sims/service/StudentService.java)): - 使用 `throws` 声明受检异常 - 强制调用方处理异常情况 ```java void addStudent(Student student) throws DuplicateStudentException; void deleteStudent(String id) throws StudentNotFoundException; ``` ### 3. 输入验证工具 [InputUtil.java](file:///D:/java/sims/src/main/java/net/zjitc/sims/util/InputUtil.java) 提供了安全的输入方法: - `nextInt()`:安全读取整数,处理 `NumberFormatException` - `nextLine()`:读取字符串,避免Scanner常见问题 --- ## 🧪 单元测试 ### 运行测试 ```bash # 运行所有测试 mvn test # 运行指定测试类 mvn test -Dtest=StudentServiceImplTest ``` ### 测试覆盖 - ✅ **DAO层测试**:验证数据存储逻辑 - ✅ **Service层测试**:使用Mockito模拟DAO,测试业务逻辑 - ✅ **异常场景测试**:验证异常是否正确抛出 ### 测试示例 ```java @Test void testAddStudent_Success() { Student student = new Student("001", "张三", 20, "男", "计算机"); boolean result = studentDAO.add(student); assertTrue(result); } @Test void testAddStudent_Duplicate() { Student s1 = new Student("001", "张三", 20, "男", "计算机"); Student s2 = new Student("001", "李四", 21, "女", "数学"); studentDAO.add(s1); assertFalse(studentDAO.add(s2)); // 学号重复,添加失败 } ``` --- ## 🔧 扩展练习 ### 初级练习 1. **完善更新功能**:在 `updateStudent()` 中补充性别和专业的修改逻辑 2. **增加输入验证**:年龄必须在 15-50 之间,姓名不能为空 3. **优化显示格式**:改进表格输出的对齐效果 ### 中级练习 1. **文件持久化**:将数据保存到文本文件,程序启动时自动加载 2. **多条件查询**:支持按专业、年龄范围查询 3. **分页功能**:当学生数量较多时,实现分页显示 ### 高级练习 1. **数据库集成**:使用JDBC连接MySQL,替换内存存储 2. **日志记录**:引入Log4j2,记录操作日志 3. **配置化管理**:使用properties文件配置系统参数 --- ## 📖 学习路线建议 ### 第一阶段:理解代码(1-2天) - [ ] 通读所有源代码,理解每行代码的作用 - [ ] 画出类图,理清类之间的关系 - [ ] 运行程序,体验所有功能 ### 第二阶段:动手实践(2-3天) - [ ] 手动敲一遍核心代码(不要复制粘贴) - [ ] 编写单元测试,覆盖所有方法 - [ ] 尝试修改功能,观察变化 ### 第三阶段:深入思考(1-2天) - [ ] 为什么要分层?不分层会怎样? - [ ] 面向接口编程的好处是什么? - [ ] 受检异常 vs 运行时异常,如何选择? ### 第四阶段:扩展提升(3-5天) - [ ] 完成上述"扩展练习"中的至少2个 - [ ] 尝试用Spring Boot重构项目 - [ ] 对比手写DI与Spring IOC的区别 --- ## ❓ 常见问题 ### Q1: 为什么不直接用ArrayList而用HashMap? **A**: HashMap可以通过学号(key)快速查找学生,时间复杂度为O(1),而ArrayList需要遍历,时间复杂度为O(n)。 ### Q2: Service层为什么要抛受检异常? **A**: 受检异常(Checked Exception)强制调用方处理,避免遗漏异常处理逻辑,提高代码健壮性。 ### Q3: 什么时候应该创建新接口? **A**: 当一个类可能被多种实现替换时(如DAO可能从内存改为数据库),就应该定义接口。 ### Q4: 如何调试程序? **A**: 在IDEA中设置断点,以Debug模式运行,逐步跟踪代码执行流程。 --- ## 🤝 贡献指南 如果你在学习过程中发现了问题或有改进建议: 1. Fork 本项目 2. 创建你的特性分支 (`git checkout -b feature/AmazingFeature`) 3. 提交你的改动 (`git commit -m 'Add some AmazingFeature'`) 4. 推送到分支 (`git push origin feature/AmazingFeature`) 5. 开启一个 Pull Request --- ## 📄 许可证 本项目仅供学习交流使用,无需许可证。 --- ## 📮 联系方式 如有问题,请查阅: - 《Java项目开发工作手册》相关章节 - Java官方文档:https://docs.oracle.com/en/java/ - Maven官方指南:https://maven.apache.org/guides/ --- ## 🌟 致谢 感谢所有学习本项目的同学!你们的进步是我们最大的动力。 > 💪 **记住**:编程是一门实践的艺术,多写代码才能进步!加油! --- **最后更新时间**:2026年6月