跳到正文
Joeplover
后端开发·2025-05-29·约 4 分钟阅读

Spring Boot 在线学习系统:第一个完整 Web 项目

基于 Spring Boot 3 + MyBatis + MySQL 搭建的在线学习平台,包含用户认证、课程管理、测验和学习进度追踪功能。

Spring Boot 学习

Spring Boot 在线学习系统:第一个完整 Web 项目

项目背景

这是基于 Spring Boot 3 搭建的第一个完整 Web 后端项目。项目包含用户注册登录、课程管理、在线测验、学习进度追踪等核心功能,完整覆盖了 Spring Boot 后端开发从数据建模到接口暴露的 CRUD 全流程。虽然功能上与后来的企业级项目相比略显简单,但涵盖了从数据库设计到前后端交互的完整闭环,是 Java Web 开发入门的最佳实践项目。 项目的定位非常清晰:不只是熟悉 Spring Boot 的 API 用法,而是通过一个完整的业务场景,理解分层架构中每层的职责和协作方式。在这个项目中首次实践了"先跑通再优化"的开发节奏——先让功能可用,后续再逐步完善代码质量和架构设计。

技术栈

Spring Boot 3.3.12(最新稳定版本,内嵌 Tomcat 容器,零配置即可启动运行)、MyBatis 3.0.4(持久层框架,XML 和注解的混合配置方式)、MySQL(关系型数据库)、Java 17(Records、Text Blocks、Switch 表达式等现代语法特性)、Spring Session(分布式会话管理,支持 JDBC 存储)、Lombok(通过 @Data、@Builder、@Slf4j 等注解大幅减少模板代码)。 每个技术选型都有明确的考量。选择 MyBatis 而非 JPA/Hibernate 是因为 MyBatis 对复杂查询有更好的控制力,且 SQL 优化空间更大。选择 Spring Session 是因为为后续多实例部署预留了扩展能力。Lombok 虽然争议较大(部分团队认为它隐藏了代码细节),但在小型项目中能显著提升开发效率。

分层架构设计

项目采用经典的三层架构:Controller -> Service -> ServiceImpl -> Mapper -> MySQL。每层的职责被严格界定:Controller 只做 HTTP 请求的接收和参数校验,不做任何业务逻辑判断;Service 层负责全部业务逻辑的实现,不直接操作数据库;Mapper 层只做数据库的增删改查操作,不做业务判断。 这种分层的核心价值在于降低了代码的耦合度。Controller 的变更不会影响 Service 的测试和运行,替换数据库实现(如从 MySQL 切换到 PostgreSQL)只需要修改 Mapper 层。每层都可以独立进行单元测试,提高了代码质量和可维护性。

核心实体与数据库设计

五个核心实体构成了系统的数据模型:User(用户)存储登录信息和基本资料、Course(课程)包含课程标题、描述和封面图片、Chapter(章节)关联到课程并按顺序排列、Quiz(测验)包含题目和选项数据、UserProgress(学习进度)记录每个用户的学习完成情况。Course 和 Chapter 是一对多关系,User 和 UserProgress 记录每个用户的学习完成情况。 数据库设计时重点考虑了两个方面:一是外键约束保证数据完整性(如删除课程时检查是否有相关章节),二是查询索引的优化。常用的查询模式(按用户查进度、按课程查章节)都建立了合适的索引,避免了全表扫描。

踩坑与解决方案

第一个坑是 MyBatis 的一对多映射。在查询课程及其章节列表时,需要使用 resultMap 的 collection 标签来映射嵌套集合。如果 SQL 语句中的列名和 Java 实体类的属性名不对应,MyBatis 会静默地返回 null 而不是报错,导致调试非常困难。解决方案是统一启用驼峰命名映射(mapUnderscoreToCamelCase=true),并在 resultMap 中显式声明所有字段映射。 第二个坑是密码加密。初期使用 MD5 存储用户密码,后来经过学习认识到这是严重的安全问题。MD5 是快速哈希算法(这正是它不适合密码存储的原因),现代 GPU 可以每秒计算数十亿次 MD5。即使加了固定盐值,彩虹表和碰撞攻击仍然可以高效破解。解决方案是改用 BCryptPasswordEncoder 加盐哈希,同样的密码每次生成的哈希值不同,验证时间可控在 50-200ms 之间。 第三个坑是 Session 共享问题。Spring Boot 默认的 Session 存储在 Tomcat 内存中,一旦部署多台服务器,用户的请求切换到另一台机器时 Session 丢失,用户被迫重新登录。解决方案是引入 Spring Session,将 Session 数据统一存储到 JDBC 数据库,所有应用实例共享同一份 Session 数据。

总结

这个项目是 Spring Boot 学习的里程碑。它不仅让我理解了分层架构、ORM 映射、密码安全等核心概念,更重要的是建立了一个可复用的项目骨架。后续的每个 Java Web 项目都可以在此基础上扩展,而不需要从零开始搭建基础设施。