ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Spring Boot交通线路查询系统毕设实战:从换乘算法到Redis缓存优化

Spring Boot交通线路查询系统毕设实战:从换乘算法到Redis缓存优化 交通线路查询系统这个毕设题我在带学生做项目时遇到的频率相当高。它听起来不复杂但真正动手以后你会发现这个题目把 Spring Boot 的核心用法基本都串起来了——数据建模、ORM 框架操作、接口设计、算法实现、缓存处理、前后端联调一样都少不了。曾有个学生跟我说做完这个系统再去面试 Java 岗被问到的 Spring Boot 问题大半都能答上几句原因很简单项目里踩过的坑就是最好的面试素材。这篇文章就围绕“springboot 交通线路查询系统”这个题目把从选题定位、技术选型、数据库设计到核心功能实现、常见问题排查的完整思路写清楚里面也包含了不少只有实际做一遍才能发现的细节。无论是准备做这个题目的毕业生还是想自己练手写一个查询系统的初学者都值得从头到尾看一遍。1. 项目整体设计与思路拆解1.1 这个题目到底在做什么交通线路查询系统简单说就是让用户输入起点和终点系统返回可行的交通线路、换乘方案、预计站点数量等信息。看起来像高德地图的一个小功能但作为毕业设计它真正考察的是你对“数据建模”和“业务逻辑”的组织能力。我从实际带项目的经验出发把功能边界拆成三个层次基础层站点管理、线路管理、站点与线路的关联关系维护这部分是后台管理员做的。核心层线路查询、站点查询、换乘方案推荐这是面向普通用户的主要功能。扩展层用户注册登录、收藏常用线路、查询历史记录、公告发布。很多学生一上来就想做得很宏大甚至想把实时公交、地图轨迹都塞进去我基本都会劝住。一个合格的毕业设计功能在精不在多把线路查询这一个核心业务做深、做透比堆砌一堆没人用的功能有价值得多。答辩时老师更关心的是你的换乘策略是怎么设计的数据结构是怎么组织的这些想清楚了系统就已经成功了一半。1.2 技术选型背后的核心逻辑技术选型是每个毕设项目的第一步也是最容易翻车的一步。这个题目我推荐的技术组合是Spring Boot 2.7.x MyBatis-Plus MySQL Redis Vue 3。每个选型背后都有明确的原因不是为了炫技。先说版本问题。Spring Boot 3.x 已经发布但它要求 JDK 17 起步很多学生的电脑上装的是 JDK 1.8学校机房更是普遍老环境。如果盲目选新版本到了部署阶段会非常痛苦。Spring Boot 2.7.x 是 2.x 系列的最后一个稳定版本既能稳定运行在 JDK 1.8 上又兼容绝大多数第三方组件是目前做毕设最稳妥的选择。热点词里频繁出现的“springboot 版本太高”“idea 不能创建 springboot 项目不能使用 jdk1.8”根源基本都是 3.x 和旧 JDK 的兼容问题我在第 4 章会详细展开。再看 MyBatis-Plus。它没有完全替代 MyBatis而是在 MyBatis 基础上提供了通用 Mapper、条件构造器、分页插件等工具写简单的单表 CRUD 几乎不用自己写 SQL。这个项目里站点管理、用户管理等都是典型的单表操作MyBatis-Plus 能把代码量压缩一大半。更关键的是它内置的代码生成器可以一键生成 entity、mapper、service、controller非常适合毕设这种开发周期有限的场景也能让你把精力集中在换乘算法这类核心业务上。最后是 Redis。可能有人觉得一个毕设用 Redis 有点多余但交通线路查询系统有一个很典型的特点线路数据基本不变但查询频率极高。同一个热门线路一天可能被查成百上千次这些查询如果每次都打到数据库既慢又没必要。把线路查询结果缓存到 Redis设置合理的过期时间接口响应速度会有肉眼可见的提升。而且“redis 在 springboot 中的使用”本身就是面试高频考点做了这个点简历上又能多写一条。1.3 数据库设计一张关联表盘活全局数据库设计是这类查询系统最关键的一步设计不好后面的算法和接口都跟着难受。我见过不少学生把“线路”和“站点”塞进一张表里用逗号分隔字段存一堆站点名查询的时候用正则去拆这种做法在数据量小的时候能跑通但没有任何扩展性答辩时也经不起追问。我推荐用四张核心表来建模表名关键字段作用t_lineid, line_name, line_type, start_time, end_time, price存储线路基本信息line_type 区分公交/地铁/长途t_stationid, station_name, lat, lng存储站点信息经纬度字段为后续扩展距离计算做准备t_line_stationid, line_id, station_id, station_order, distance_next线路与站点的关联表station_order 记录站点在线路上的先后顺序t_userid, username, password, phone, create_time用户信息用于注册登录和收藏功能核心是 t_line_station 这张关联表。它把“线路”和“站点”的多对多关系解耦出来每一条记录代表“某条线路上的某个站点以及它在整条线路上的顺序位置”。为什么要单独存 station_order因为线路查询最关键的就是顺序。比如 1 路公交从 A 站开到 E 站中间经过 B、C、D站点之间是有先后关系的只有存下顺序才能算出“从 A 站坐 3 站到 D 站”这种结果。这里有一个我在实际设计中反复强调的细节关联表里最好再加上 next_distance 字段记录当前站点到下一站的距离。有了它换乘方案可以算出总距离给用户提供一个“距离优先”的排序条件。如果一开始没设计这个字段后面想补就得改表结构数据迁移很麻烦。1.4 项目目录结构与代码分层Spring Boot 项目不是把代码随便堆在一起就行清晰的包结构对毕设的意义在于答辩时能讲出逻辑后续加功能时不会乱。我的习惯是建一个简洁的 controller/service/mapper/entity 四层结构再额外加一个 common 包放统一返回结果和异常处理。com.example.transit ├── controller // 接口层接收请求返回统一结果 ├── service // 业务层线路查询、换乘计算等核心逻辑 ├── mapper // 数据访问层继承 BaseMapper 接口 ├── entity // 实体类与数据库表字段对应 ├── dto // 数据传输对象用于接口入参和出参 ├── common // 统一返回结果、异常处理、常量类 └── config // 配置类如 Redis 配置、MyBatis-Plus 配置这样的分层方式和后端开发岗位的主流做法基本一致以后出去实习也能很快适应。有一点要注意不要把业务逻辑写在 Controller 里。之前看过一个学生的代码换乘算法直接在 Controller 方法里写了 200 行接口一多整个类就变得没法维护。业务逻辑放在 Service 层Controller 只做参数接收和结果返回这既是规范问题也是代码可读性的问题。2. 核心功能拆解与 Spring Boot 落地要点2.1 换乘方案怎么算从 BFS 到最少换乘策略查询功能听起来简单但“换乘方案计算”是整个项目真正的技术难点也是答辩时老师最可能追问的地方。直白地说从一个站点到另一个站点如果两条线路能直达问题很简单但现实场景里更常见的是一趟线路到不了需要中途换乘。怎么用代码找到“换乘次数最少”的方案这就要用到图论里的思路。我先把问题抽象成图模型把每个站点看成图的顶点把每条线路看成“可以一次性到达的边集合”。注意这里我们不能直接把线路当边因为换乘约束的是“在同一站点从线路 A 换到线路 B”所以要基于“线路”而不是“站点”来建图。实现时我推荐用 BFS广度优先搜索因为 BFS 天然适合求“最少换乘次数”。伪代码逻辑是这样的从起点站出发先找到所有经过起点站的线路再从这些线路上的每一个站点出发找所有经过该站点的其他线路逐层扩展直到找到包含终点站的线路。每一层扩展就是一次换乘。public ListTransferPlan findTransferPlans(Integer startStationId, Integer endStationId) { // 1. 找到所有经过起点站的线路 ListLine startLines lineStationMapper.selectLinesByStationId(startStationId); // 2. 如果某条线路直接经过终点站直接返回直达方案 // 3. 否则用队列做 BFS记录换乘路径 QueueListInteger queue new LinkedList(); // 存储线路 id 序列 SetInteger visited new HashSet(); for (Line line : startLines) { ListInteger path new ArrayList(); path.add(line.getId()); queue.offer(path); } while (!queue.isEmpty()) { ListInteger currentPath queue.poll(); Integer currentLineId currentPath.get(currentPath.size() - 1); // 4. 如果当前线路经过终点站返回方案 // 5. 否则遍历当前线路所有站点再找经过这些站点的其他线路加入队列 } }这里一个关键设计是 visited 集合记录哪些线路已经被访问过避免 BFS 死循环。试想一下A 线路经过站点 XX 又连着 B 线路而 B 线路又经过站点 YY 又连回 A 线路如果没有 visited 标记程序就会在两条线路之间无限循环。2.2 站点与线路关键词搜索的优化思路除了换乘查询用户使用频率最高的就是搜索框。用户输入“火车站”或“人民广场”系统要能快速返回匹配的站点或线路列表。最常见也最容易被学生写错的地方就是用LIKE %关键词%直接查数据库数据量小的时候没问题可一旦站点表超过几万条这种写法性能会明显下降。更合理的做法是分两步走。第一步先把高频搜索词的结果放进 Redis 缓存比如用户搜过“火车站”系统把站点列表缓存起来第二次再搜直接命中缓存不再查数据库。第二步主查询用 MySQL 的索引优化站点名称字段建立普通索引配合LIKE 关键词%前缀匹配让数据库走索引而不是全表扫描。缓存这块直接使用 Spring 的Cacheable注解就能实现不过我更推荐手动用 RedisTemplate 来实现原因是在毕设答辩时老师如果问“这个查询为什么快”你能说出“先查缓存、缓存没有再查数据库、回填缓存”的完整链路比笼统说一句“用了缓存注解”更有说服力。public ListStation searchStations(String keyword) { // 1. 先从 Redis 查 String cacheKey station:search: keyword; Object cached redisTemplate.opsForValue().get(cacheKey); if (cached ! null) { return JSON.parseArray(cached.toString(), Station.class); } // 2. 缓存没有查数据库 ListStation stations stationMapper.selectList( new LambdaQueryWrapperStation() .likeRight(Station::getStationName, keyword)); // 3. 回填缓存设置 30 分钟过期 redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(stations), 30, TimeUnit.MINUTES); return stations; }有一点要提醒缓存数据一定要设置过期时间否则线路调整后用户看到的还是旧数据。公共交通信息偶尔是会发生变动的哪怕是毕设也要把“缓存失效”这件事考虑进去。2.3 Spring Boot 自动装配机制在项目里的体现做这个项目时很多学生都会被 Spring Boot 那一堆注解搞晕SpringBootApplication、RestController、Service、Autowired、ConfigurationProperties这些注解到底是怎么生效的我在带学生的过程中发现与其死记硬背注解用法不如把 Spring Boot 的“自动装配”原理弄明白理解了它所有注解都变得顺理成章。简单说Spring Boot 的启动类上的SpringBootApplication是一个组合注解包含SpringBootConfiguration、EnableAutoConfiguration、ComponentScan。其中EnableAutoConfiguration是核心它通过读取依赖 jar 包里的META-INF/spring.factories文件找到大量配置类再通过ConditionalOnClass、ConditionalOnMissingBean这些条件注解判断“当前项目有没有这个类、有没有这个Bean”有就自动配置。这就是为什么你只要引入spring-boot-starter-data-redis依赖Spring Boot 就会自动帮你创建 RedisTemplate 的实例前提是你配好了连接信息。理解这个原理后面试题“springboot 自动装配原理”就能答得很清楚了。更实际的好处是项目里如果要自定义一个全局配置你就知道该用ConfigurationProperties配合EnableConfigurationProperties把配置绑定到实体类上而不是在代码里各处写Value取配置。配置一多Value的写法会显得特别乱。2.4 统一返回结果与全局异常处理接口返回格式在前后端分离项目里非常重要。如果你让每个接口返回的数据结构都不一样前端对接的时候会哭死。我习惯定义一个统一的结果类 Result包含 code、message、data 三个字段。成功时 code 为 200失败时 code 为 500这样前端只需要判断一次 code 就能走完整个流程。全局异常处理用RestControllerAdvice配合ExceptionHandler实现。这个类可以把所有 Controller 层抛出的异常统一拦截转成 Result 对象返回避免出现一长串堆栈信息直接暴露给前端的情况。除了业务异常还可以在全局异常里处理参数校验异常、数据库访问异常等前端只需要针对不同的 code 给出不同提示。3. 实操过程与核心环节实现3.1 从零搭建项目版本、初始化和 Maven 配置很多学生的第一个坑就出现在创建项目这一步尤其是 IDA 创建 Spring Boot 项目时选不到合适的版本或者下载依赖慢得像蜗牛。这里我直接给一套稳妥的搭法。第一步确认本机环境。JDK 1.8 Maven 3.6.3 是经典组合不需要追求高版本。IDEA 不建议用太老的版本2022.x 以上对 Spring Boot 的支持都很成熟。很多人问 Gradle 和 Maven 选哪个毕设我强烈建议 Maven因为搜索资料时 Maven 的解决方案更多遇到坑更好查。第二步创建项目时注意 Spring Initializr 服务地址。如果你用的是 IDEA 自带的 start.spring.io在国内网络环境下经常超时。这里可以换成阿里云的初始化服务地址创建速度快得多而且它默认提供的依赖版本更符合国内开发环境的习惯。这个细节看起来不起眼但能帮你省下大量等待时间。第三步配置 Maven 的仓库镜像。打开 Maven 的 settings.xml 文件把中央仓库地址改为阿里云镜像。改完之后下载 Spring Boot 相关依赖的速度会有质的提升。一个古典的问题就是pom.xml 里依赖还没下完就急着写代码结果代码里所有 import 全部标红这是网络问题不是代码问题。创建完成后检查 pom.xml 里的 Spring Boot 版本。如果是 2.7.x可以放心用 JDK 1.8如果你不小心选到了 3.x 版本而本机是 JDK 1.8那就要把版本改回 2.7.x否则启动会直接报错。版本对应关系我放在第 4 章方便对照。3.2 配置文件数据源、Redis 与 MyBatis-Plus 的整合Spring Boot 的配置集中在 application.yml 里把这个文件配好项目就等于成功了一半。下面是一份可以直接参考的核心配置server: port: 8080 servlet: context-path: /api spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/transit_system?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai username: root password: 123456 redis: host: localhost port: 6379 database: 0 timeout: 5000ms mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0有几个容易被忽略的点。MySQL 连接地址必须加上 serverTimezone 参数不然会有时区报错。MyBatis-Plus 的log-impl配置建议开发阶段保留它会在控制台打印每一条 SQL排错时非常有用但上线前记得关掉否则日志文件会非常大。如果要做多数据源比如同时连 MySQL 和 SQLServer可以引入 dynamic-datasource 依赖然后在配置里写多个 datasourceService 层用DS(slave)注解指定走哪个数据源。这个点可以作为项目的加分项但前提是你确实有这样一个业务需求不然就是画蛇添足。3.3 核心代码实现换乘查询接口的完整链路换乘查询是整个系统最核心的接口我们从头到尾串一遍。后端接口定义为POST /api/line/transfer入参是起始站点名称和目标站点名称出参是换乘方案列表。第一步Controller 接参并调用 ServiceRestController RequestMapping(/line) public class LineController { Autowired private TransferService transferService; PostMapping(/transfer) public ResultListTransferPlanVO transfer(RequestBody TransferQueryDTO dto) { ListTransferPlanVO plans transferService.queryTransferPlan(dto.getStartStation(), dto.getEndStation()); return Result.success(plans); } }第二步Service 里做核心计算。先用 Redis 缓存判断是否已有结果有就直接返回没有再执行 BFS 换乘算法。第三步算法拿到换乘线路序列后还要补上每个换乘站点的名称、乘坐方向、途经站数。这一步需要写一个辅助方法通过 t_line_station 表找出“换乘站点在两条线路上的具体位置”比如从 1 路换到 5 路要能算出你在 1 路上坐了几站、在 5 路上准备坐几站换乘点在哪。换乘站点的上下车站关系是这个项目最绕的地方。我的建议是写一个 LineStationService专门处理“线路经过的站点有序列表”这类查询核心业务直接复用不要每个方法都写一遍 SQL。代码写完之后最好手工构造几组测试数据验证一下算法的正确性不要直接把网上扒下来的数据塞进去否则数据格式不一致很容易出现查不到方案的情况。3.4 前端 Vue 对接与跨域处理前端用 Vue 3 Element Plus 是当下最常见的组合和后端通过 RESTful API 对接。前端项目里需要配置一个代理把/api开头的请求转发到后端的localhost:8080。vite.config.js 里的核心配置如下export default defineConfig({ server: { port: 3000, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })很多学生第一次联调时看到浏览器控制台报跨域错误第一反应是去后端加CrossOrigin注解这其实只解决了一半问题。有了上面的代理配置前端访问http://localhost:3000/api/line/transferVite 开发服务器会自动帮你转发到后端浏览器和前端服务器之间不存在跨域自然也就没有跨域问题了。后端加的CrossOrigin属于备份方案两边都配上也没有问题。前端页面重点做好三块线路查询页输入起点和终点展示换乘方案列表、站点搜索页输入关键词展示站点和经过线路、后台管理页管理员维护线路与站点数据。页面数量不用太多但每个页面都要和真实业务挂钩尤其要注意展示换乘方案时把“乘坐 X 路从 A 站上车坐 4 站到达 B 站换乘 Y 路”这类描述清晰呈现给用户这是用户体验的关键。如果 2025 年的你想给项目加一些亮点可以考虑把 Spring Boot MCP 引入进来把线路查询能力封装成 AI 助手可以调用的工具用户通过聊天就能问“从人民广场到火车站怎么走”。但那属于进阶玩法先把基础查询功能做扎实再说。4. 常见问题与排查技巧实录4.1 Spring Boot 版本太高引发的连环坑我见过太多学生在这个问题上浪费时间。症状通常是这样的电脑装了 JDK 21用 IDEA 新建 Spring Boot 项目时默认拉到 3.x 版本代码写完后启动直接报错。报错信息五花八门最多的是java.lang.UnsupportedClassVersionError意思是编译版本的 class 文件在当前 JVM 上跑不了。问题的根源在于版本匹配。Spring Boot 3.x 要求 JDK 17 及以上版本内部包名也从javax.*改成了jakarta.*。如果强行用 JDK 1.8 跑 Spring Boot 3.x 项目包名就找不到代码根本编译不过。反过来JDK 21 跑 Spring Boot 2.7.x 也偶尔会有兼容问题。我给你的建议也是我反复验证过的版本组合表Spring Boot 版本JDK 版本包名适用场景2.7.xJDK 8 / 11javax.*毕设推荐资料多兼容好3.0.x - 3.2.xJDK 17 / 21jakarta.*新项目可以试但资料相对少3.3.x 及以上JDK 17 / 21jakarta.*生产级新特性毕设不推荐如果电脑上已经装了高版本 JDK又不想卸载重装可以在 IDEA 的 Project Structure 里单独给项目指定 JDK 1.8前提是你机器上必须真实安装了 JDK 1.8只在 IDEA 里选没有用。装了多个 JDK 时还要检查JAVA_HOME环境变量指向谁IDEA 里 Maven 用的 JRE 配置也要跟着改三个地方保持一致才不会启动时报找不到主类。4.2 数据库连接与缓存相关的坑开发过程中数据库连接问题是最常见的。报错Access denied for user rootlocalhost说明数据库账号或密码不对。报错Unknown database transit_system说明你还没有创建这个数据库用 Navicat 或命令行执行CREATE DATABASE transit_system DEFAULT CHARACTER SET utf8mb4;就能解决。注意字符集一定要指定 utf8mb4不然中文站点名存储和查询都会出问题。还有一个很经典的坑Public Key Retrieval is not allowed。这个错误出现在 MySQL 8.0 以上版本连接 URL 里加上allowPublicKeyRetrievaltrue即可。MySQL 驱动版本也要注意Spring Boot 2.7.x 默认引入的是 MySQL Connector/J 8.0.x如果你手动在 pom.xml 里换成了 5.1.x驱动类和 URL 写法都会不一样这也是查都查不出来的隐藏问题。Redis 连接不上是第二大类问题。检查三个地方Redis 服务有没有启动命令行redis-cli ping返回 PONG 说明正常、配置文件的端口是否一致、Redis 是否设置了密码。这里有一个经常被忽略的细节Spring Boot 2.x 里连接 Redis 默认用的 Jedis需要单独引入依赖而 Spring Boot 2.7.x 如果只想快速使用可以直接用spring-boot-starter-data-redis它默认用的是 Lettuce不需要额外配置就能跑起来。我建议毕设用 Lettuce 就行少一个依赖少一个坑。4.3 启动异常与依赖冲突排查Spring Boot 项目启动失败是一个高频问题。排查时建议遵循“看日志、定位、再看日志”的顺序不要瞎改代码。启动时最常看到的错误是端口占用Port 8080 was already in use。这种情况在 Windows 上很常见之前的项目没关干净就重新启动。命令行执行netstat -ano | findstr 8080找到占用端口的进程 PID然后在任务管理器里结束它就行。依赖冲突的问题也很典型症状是启动时出现NoSuchMethodError或ClassNotFoundException这类问题在排查时先看 pom.xml 里有没有重复引入相同功能的依赖再看依赖版本是否有冲突。常用的办法是执行mvn dependency:tree查看依赖树找出冲突的 jar 包用exclusion排除掉不需要传递引入的依赖。这个时候你会发现依赖尽量少而精才是王道不要什么都往 pom.xml 里加。 提示如果你遇到 Failed to configure a DataSource: url attribute is not specified 这个错误先不要慌。这个报错的本质是 Spring Boot 启动时自动装配了数据源但找不到连接配置。检查一下 application.yml 是否被正确加载或者你在测试类里启动了 Spring 上下文但没配置数据源。最简单的解决方法是把测试类加上 SpringBootTest并且保证测试环境有完整的配置。 ### 4.4 答辩高频追问整理理解比背答案更重要 做毕设最终要过答辩这一关我把带学生时被问得最多的几个 Spring Boot 相关问题整理出来每个都附带通俗的解释思路。 第一个问题几乎是必问的Spring Boot 自动装配的原理是什么回答思路是启动类上的 SpringBootApplication 包含 EnableAutoConfiguration它会扫描所有 jar 包里的 META-INF/spring.factories 文件把里面声明的配置类加载进来再通过 ConditionalOnClass 等条件注解判断这些配置是否生效。最后利用 ConfigurationProperties 把配置文件里的值绑定到属性类上完成自动配置。 第二个问题Spring Boot 的 starter 是什么为什么引入一个依赖就能用回答思路starter 是一组相关依赖的组合包比如 spring-boot-starter-web 内部把 Spring MVC、Tomcat、Jackson 这些 Web 开发需要的库都打包好了你不必一个个去引依赖。加上 EnableAutoConfiguration 的自动装配就实现了“引入即用”。 第三个问题项目里的事务怎么处理哪些场景事务会失效这个项目里线路和站点新增、修改属于写操作建议在 Service 方法上加上 Transactional。事务失效的常见场景包括方法内部自调用同类里调用另一个 Transactional 方法、异常被 catch 住导致事务感知不到、访问权限不是 public 导致 Spring AOP 无法代理。回答时能举一个自己项目中实际的例子比单纯背理论高出一个档次。 第四个问题为什么用 Redis 而不是直接查数据库回答思路交通线路数据变化频率低、查询频率高属于典型的“读多写少”场景。把高频查询结果缓存到 Redis可以减少数据库压力、降低接口响应时间。同时还要强调我设置了合理的过期时间并且在线路数据更新时会主动删除缓存保证数据的最终一致性。这套思路说完基本就能让老师看到你是有真实项目经验的。 ### 4.5 避坑速查表 下面这张表是我整理的高频问题速查建议你保存一份做项目过程中遇到问题先来查一遍再开百度 | 问题现象 | 常见原因 | 快速解决方案 | |---|---|---| | 创建项目时下载依赖失败 | 中央仓库访问慢 | 配置阿里云 Maven 镜像 | | 启动报 UnsupportedClassVersionError | JDK 与 Spring Boot 版本不匹配 | 按版本对应表调整 | | 端口被占用 | 上一次程序未停止 | netstat 查 PID任务管理器结束进程 | | 数据库连不上 | 密码错误、数据库未创建 | 检查连接配置和数据库名称 | | 中文乱码 | 数据库字符集不是 utf8mb4 | 统一设置 utf8mb4 | | Redis 连接超时 | Redis 服务未启动或密码错误 | 检查服务状态和密码配置 | | 接口返回 500 | 全局异常没有兜底 | 写一个全局异常处理类 | | 前端跨域报错 | 前后端地址不一致 | 用 Vite proxy 配置代理 | 我发现一个规律学生做项目花在“配置问题”上的时间往往比写业务代码还多。这其实是正常现象我刚接触 Spring Boot 那几年也经常在 Maven 依赖和版本问题上折腾到大半夜。但正是因为踩过这些坑后来看项目报错才会条件反射般地想到定位方向这算是这个阶段最宝贵的收获。 做这个题目我最后总会提醒学生一件事不要急着追新版本、抄大项目把 Spring Boot 本身的基本功打牢把换乘算法讲明白把一个查询接口的完整链路吃透这个毕业设计就已经达到了“优秀”的底线。等你把自动装配、缓存、事务这些点都弄懂你会发现很多看上去高大上的项目核心原理也就是这么回事。
返回列表