ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Spring Boot电子产品销售系统:从数据库设计到答辩通关的实战指南

2026/9/26 2:52:18 拓冰建站 浏览量
Spring Boot电子产品销售系统:从数据库设计到答辩通关的实战指南 每年到了课程设计和毕业设计的季节十个学生里至少有三四个会选“基于Spring Boot的XX系统”这类题目。电子产品销售系统更是经典中的经典——题目常见、资料好找、功能完整但真正能把它讲明白的同学反而不多。很多人拿到一份带源码、带数据库脚本、带万字文档的项目包后第一反应是先把项目跑起来然后修改封面上的姓名、学号、指导教师。这本身没有错但如果连订单表和购物车表的关系都说不清库存扣减为什么不会超卖也答不上来那答辩的时候大概率会被问到当场卡壳。这篇文章不打算绕弯子。我就从这类“基于Spring Boot的电子产品销售系统”的实际项目出发把最容易被忽略但又最重要的东西拆开讲技术栈怎么选、数据库表怎么设计、登录到下单的核心链路过一次、源码拿到手之后怎么最快读懂、万字文档怎么写得让答辩老师挑不出毛病还有我踩过的那些坑。无论你是拿到了完整源码想二次开发还是准备从零开始自己撸一个这套思路通用。1. 项目拆解这个“电子产品销售系统”到底要做什么1.1 为什么课程设计都选这个题目电子产品销售系统是个典型的电商系统但它比“在线购物”更聚焦卖的是手机、耳机、键盘、鼠标这类数码外设。它看起来没有“某某管理系统”那么枯燥业务规则又比社交软件简单非常适合在一学期内做完。从老师角度讲它覆盖了用户管理、商品管理、购物车、订单、库存、统计报表凡是JavaWeb课程里教过的东西基本都能体现从学生角度讲它贴近日常购物习惯需求不用凭空编打开京东、淘宝就能照着拆分讲起来也有东西可聊。这套系统最大的优势是“麻雀虽小五脏俱全”。它不是简简单单的增删改查而是牵扯到两张以上的表联动、状态流转、事务处理、权限控制。举个例子用户下单时购物车要清空、订单要新增、订单明细要写入、商品库存要扣减这四个操作必须在一个事务里完成否则就会出现“订单生成了库存却没减”的严重错误。这类业务逻辑才是答辩时老师真正关注的考点。1.2 需求边界用户端与管理端的分工我拿到任何项目源码第一件事不是看代码而是先看角色和功能清单。普通电子销售类系统基本是两类角色再加上一个公共模块。用户端面向注册用户核心功能包括注册、登录、浏览商品列表、按分类或关键词搜索、查看商品详情、加入购物车、修改购物车数量、提交订单、模拟支付、查看订单状态、管理收货地址、编辑个人资料。有些系统还会加收藏功能但收藏不是必需品没有也不影响核心流程。管理端面向管理员功能一般有账号登录、商品分类管理、商品上下架与库存修改、订单列表查询、订单发货、查看销售统计。这里要注意很多同学容易把管理员功能和用户功能混在一起。管理员要看的是后台管理页面不是用户商城首页管理员操作的是“上架商品、处理订单”不是“下单买手机”。区分好这两条线需求分析才立得住。还有一个公共模块需要提前想清楚文件上传。商品图片不可能都写在数据库里通常会把图片传到本地目录或云存储数据库只保存图片访问路径。像这种细节在课程设计文档里写一句“图片采用文件上传方式数据库存储路径”观感立刻就不一样了。1.3 技术栈如何选择与权衡标题里已经强调“基于Spring Boot”所以后端框架没有任何悬念就是Spring Boot。但完整技术栈怎么配决定了你后面写代码和写文档的难度。最稳妥的组合是Spring Boot MyBatis-Plus MySQL Thymeleaf。如果项目包源码里用的是这个组合恭喜你它是课程设计中最主流的搭配资料最多坑也最少。Spring Boot负责提供Web环境、自动配置和事务管理MyBatis-Plus承接数据库操作内置分页插件和条件构造器写单表CRUD能省下一大半重复代码MySQL存数据Thymeleaf做服务端渲染不用单独再启一个前端项目。有些毕设会把前端换成Vue采用前后端分离。这种方案看起来更“现代化”但代价是你要同时掌握前端工程化还要处理跨域答辩时复杂度成倍上涨。对于课程设计阶段如果你的目标是稳、是能讲明白我建议优先选择服务端渲染的Thymeleaf方案。它可以把所有页面跳转和接口调用都集中在一个Spring Boot项目里逻辑连贯调试也方便。数据库方面MySQL 5.7 或 8.0 都可以本地开发推荐5.7因为网上遇到问题的案例最多几乎每个错误都能搜到解决方案。JDK选择1.8或11别追求最新版本Spring Boot 2.x 和 JDK 8 是经过无数人验证的黄金组合。2. 数据库设计销售系统的“地基”怎么打2.1 实体关系梳理先画清楚表之间的连线很多同学把“写SQL”当成数据库设计这是大忌。数据库设计的第一步是画概念模型明确有哪些实体实体之间是什么关系。这套系统的实体其实很清晰我先列出来用户user注册登录的主体可能有多条收货地址。收货地址address属于某个用户一个用户对应多条地址。商品分类category商品从属于一个分类分类可以有多级但课程设计做一级分类就够了不要给自己挖太多坑。商品product属于某个分类库存、价格、销量都挂在商品上。购物车cart用户和商品的关联记录某个用户加入了某商品多少件。订单orders用户提交订单后生成记录收货地址快照、总金额、支付金额、订单状态。订单明细order_item一个订单包含多个商品订单明细就是订单和商品的关联保存下单时的商品名、价格、数量、小图。关系可以这样梳理用户与订单是1对N用户与购物车是1对N订单与订单明细是1对N商品与订单明细是1对N商品与分类是N对1。购物车表和订单明细表本质上都是“关联表”但购物车是临时数据可以反复修改订单明细是历史快照下单后不允许变动。这个区别理解透了你写代码时就不会把两张表混为一谈。为什么订单明细要保存“商品名称、商品图片、商品价格”不是明明可以关联商品表查询吗关键就在“快照”二字。商品价格和名称随时可能改但用户已经下单的商品必须以下单那一刻的信息为准。这也是一个非常常见的答辩考点提前想明白回答时能加分。2.2 核心表结构与建表要点下面给出一个我常用的核心表结构具体字段类型完全可以直接复用。注意ID统一用自增主键金额字段用decimal手机号/电话用varchar因为电话号码不需要参与数值运算用整数反而可能丢前导零。用户表user字段名类型说明user_idbigint主键自增usernamevarchar(30)用户名唯一passwordvarchar(100)密码BCrypt加密后长度约60nicknamevarchar(30)昵称phonevarchar(20)手机号avatarvarchar(255)头像路径roletinyint角色0普通用户1管理员create_timedatetime注册时间is_deletedtinyint逻辑删除标记0否1是商品表product字段名类型说明product_idbigint主键category_idbigint所属分类product_namevarchar(100)商品名称descriptiontext商品描述pricedecimal(10,2)价格stockint库存salesint销售量imagevarchar(255)商品主图statustinyint状态0下架1上架create_timedatetime创建时间is_deletedtinyint逻辑删除标记订单表orders字段名类型说明order_idbigint主键order_novarchar(32)订单号唯一user_idbigint下单用户receiver_namevarchar(30)收货人姓名receiver_phonevarchar(20)收货电话receiver_addressvarchar(255)完整收货地址total_amountdecimal(10,2)商品总金额pay_amountdecimal(10,2)实际支付金额可含优惠statustinyint0待付款1已付款2已发货3已完成4已取消payment_typetinyint支付方式1模拟支付create_timedatetime下单时间pay_timedatetime支付时间ship_timedatetime发货时间finish_timedatetime完成时间订单明细表order_item字段名类型说明item_idbigint主键order_idbigint所属订单product_idbigint商品IDproduct_namevarchar(100)商品快照名product_imagevarchar(255)商品快照图pricedecimal(10,2)下单时价格quantityint购买数量购物车表cart我的建议不要做太多字段cart_id、user_id、product_id、quantity、checked是否选中供下单时筛选、create_time。为什么需要checked因为用户在购物车里勾选哪几项才提交订单这个状态必须记录否则下单逻辑只能“全选”体验很差。对于课程设计而言这个字段是个亮点。建表时还有三个最关键的点主键索引是必须的外键冲突容易出问题订单号要唯一。课程设计阶段我通常不推荐建物理外键因为一旦涉及删除或者更新级联约束会让调试变得很难受。用逻辑外键就够了表和表通过Java代码来控制关联关系。2.3 初始化数据与字段规范拿到数据库脚本后不要只导入空表就完事。系统要能演示必须有初始化数据管理员账号。课程设计大多数时候用一个admin用户。密码不要用明文推荐在SQL里预置BCrypt加密好的字符串让注册功能也使用同样的加密算法这样“后台登录”和“用户注册”共用一套认证逻辑。测试商品数据。电子产品销售系统至少准备六到八个商品手机、无线鼠标、机械键盘、耳机、显示器、USB扩展坞。每个商品要有关联分类、合理的价格、库存和一张网络图片地址。状态字段的默认值必须设置好。商品status默认1表示上架订单status默认0表示待付款逻辑删除is_deleted默认0。这样在写代码时很多地方可以减少一次显式赋值。值得一提的是订单号。不要用自增ID当订单号否则用户从订单号能猜到系统一共下了多少单也会让后续扩展变得很麻烦。订单号我习惯用“时间戳随机数”拼接比如yyyyMMddHHmmss 4位随机数字然后加唯一索引。这个细节写进文档里比空谈“统一规范”有说服力得多。3. 核心功能模块实现从登录到下单的完整链路3.1 登录注册与权限拦截后端实现的第一步是登录注册。登录的逻辑并不复杂但有两个细节是常见的失分点一是密码不能明文存储二是需要拦截器保护接口。密码加密推荐Spring Security里的BCryptPasswordEncoder。别被Spring Security这个名字吓到你可以不引入全部安全框架只单独用这个工具类。注册时对密码做加密登录时用matches方法比对数据库里永远不出现明文密码。答辩时问“为什么不用MD5”你可以回答MD5加盐也可以但BCrypt每次生成的哈希值不同、自带盐值、计算成本可控更适合密码存储。权限拦截用Spring MVC的HandlerInterceptor。我一般会写两个拦截器一个处理管理员权限一个处理用户登录状态。用户端除了登录、注册、商品浏览、商品搜索这类公开接口其它路径都必须校验session中是否有user对象。这里有一个容易被忽略的大坑拦截器的放行路径必须写全。很多项目启动后前端页面能打开但一点“加入购物车”就跳回登录页排查半天发现是cart接口没放行到拦截器之外不对正确解释应该是拦截器拦截了所有请求但没有排除商品详情页内的异步请求路径。写拦截器时务必把静态资源 /static/、登录页 /login、注册接口 /register、商品列表 /product/list 这几个路径都放行。我在带学生调试时至少见过十次因为路径少写了一个斜杠导致的诡异问题。3.2 商品展示与分页检索商品列表是销售系统的门面也是后端最常用的查询场景。使用MyBatis-Plus时分页查询的标配写法是PageProduct page new Page(current, size); LambdaQueryWrapperProduct wrapper new LambdaQueryWrapper(); wrapper.eq(Product::getStatus, 1); if (StringUtils.hasText(keyword)) { wrapper.like(Product::getProductName, keyword); } wrapper.orderByDesc(Product::getSales); PageProduct result productService.page(page, wrapper);这段代码里有三个关键点需要解释。LambdaQueryWrapper是MyBatis-Plus的条件构造器优点是用Java方法引用写字段名不写字符串。这样字段改名会引起编译错误而不是在SQL执行时报错对于课程设计来说能在编译期发现的问题都是好问题。keyword参数使用like查询时MyBatis-Plus会使用预编译占位符天然防止SQL注入。如果你是自己拼SQL一定要用#{keyword}而不是${keyword}。这个知识点几乎每次答辩都会问提前背熟“预编译可以防止SQL注入”这句话还不够最好能用自己的话讲一遍原理。分页插件的配置别忘了。在配置类里加上PaginationInnerInterceptor并指定数据库类型为MySQL否则分页不生效。很多同学项目跑起来发现分页查出来全是同一条数据大概率就是少了这个配置。分页插件会在执行查询前自动把分页参数拼进SQL生成一条带LIMIT的语句和一条COUNT语句对于课程设计完全够用。商品详情页通常还要做相似推荐最简单的实现是“同分类下随机取4条”。在毕业论文里可以写成“基于分类标签的简单推荐策略”这样既低调又有说法。3.3 购物车、订单与库存扣减这条链路是整个系统的心脏也是最能体现水平的地方。我建议所有代码都写一遍不要直接复制理解透了至少能应对三个高频答辩题。购物车加购逻辑相对简单先查购物车是否已有同一用户同一商品有就加数量没有就新增一条。这个操作需要注意字段唯一性可以在数据库为user_id和product_id建联合索引并先查后改。最重要的事务逻辑发生在提交订单。伪代码如下Transactional(rollbackFor Exception.class) public Order submitOrder(Long userId, Long addressId) { // 1. 查询该用户购物车内所有checked1的商品 ListCart cartList cartService.getCheckedCart(userId); // 2. 创建订单主记录订单号、总金额、状态0 Order order createOrder(userId, addressId, cartList); // 3. 遍历购物车逐条扣库存并生成订单明细 for (Cart cart : cartList) { boolean success productMapper.deductStock(cart.getProductId(), cart.getQuantity()); if (!success) { throw new RuntimeException(库存不足); } orderItemMapper.insert(...); } // 4. 清空已选购物车 cartService.removeCheckedCart(userId); return order; }注意第3步的扣库存方法我推荐用一条带条件判断的UPDATE语句而不是先查库存再判断再UPDATE。UPDATE product SET stock stock - #{quantity}, sales sales #{quantity} WHERE product_id #{id} AND stock #{quantity}这样做的原因是并发安全。假设库存只剩1件两个用户同时下单各自把库存查出来都是1然后各自做判断最终可能出现两个人都下单成功但库存变成-1的情况。而上面的SQL用WHERE stock #{quantity}约束只有库存足够才会影响行数返回受影响行数为0就说明库存不足直接抛异常回滚。这个思路在数据库层面保证了原子性比在Java代码里加锁更简单可靠。为什么整个方法要加Transactional因为下单涉及多次INSERT和UPDATE任何一个操作失败前面的写操作也必须撤销否则订单没生成但库存扣了、或者购物车被清空但订单失败数据全乱。Spring事务默认只回滚RuntimeException所以rollbackFor要写成Exception.class把受检异常也算进去。这个细节很多工作两三年的开发都会忽略放在课程设计里绝对是加分项。3.4 后台管理与统计报表后台管理功能不用做得很华丽但该有的必须有商品列表、商品编辑、上下架、订单列表、订单状态修改。订单状态流转要定义清楚。我一般会用常量或枚举来定义而不是散落魔法数字0待付款、1已付款、2已发货、3已完成、4已取消。后台的“发货”操作就是把状态从1改成2并写入ship_time用户端的“确认收货”是把状态从2改成3并写入finish_time。每次改状态前要校验当前状态防止用户从待付款直接跳到已完成。这种校验写起来很简单但很多初学者想不到。文档里写一句“系统实现订单状态机的有序流转”老师一看就明白你懂。统计报表最怕复杂课程设计阶段做一个“近七天销售额”的折线图就够了。后端SQL可以用日期函数SELECT DATE(create_time) AS day, SUM(pay_amount) AS total FROM orders WHERE status IN (1,2,3) AND create_time DATE_SUB(CURDATE(), INTERVAL 6 DAY) GROUP BY DAY(create_time) ORDER BY day前端用ECharts画图后端返回一个接口数据格式是日期和金额的数组。不要把SQL只写在Mapper接口里的XML中也可以使用MyBatis-Plus的QueryWrapper配合select不过统计类SQL用XML更直观。如果项目用的是Thymeleaf直接把初始化数据塞到Model里再在前端用JavaScript组装ECharts的数据源即可。4. 源码阅读与二次开发别让资料只停在“能运行”4.1 项目快速初始化步骤不管从哪拿到项目包第一步肯定是在本机跑起来。我经常告诉学生能运行是1其余一切分析都是0跑不起来后面全白搭。我的建议步骤是确认环境JDK 1.8、Maven 3.6、MySQL 5.7、IDEA。打开IDEA选择Open定位到项目根目录等待Maven下载依赖。修改application.yml或application.properties把数据库地址、用户名、密码改成自己的。创建数据库字符集选utf8mb4执行项目里提供的SQL脚本。直接运行启动类看到“Tomcat started on port(s): 8080”就说明成功了。访问前台首页再用admin账号登录后台。这里最大的变数是Maven依赖下载慢。国内网络环境我强烈建议在Maven的settings.xml里配置阿里云镜像不然卡在下载依赖这一步会怀疑人生。IDEA里也能配置File - Settings - Maven - user settings file。配置镜像之后再reimport速度是质变。端口被占用也很常见。启动报“Port 8080 was already in use”可以换端口也可以杀掉占用进程。但换端口后要注意前端访问路径写的是不是硬编码8080最好统一使用相对路径这样换端口也不用改页面。4.2 源码包结构怎么读拿到完整源码不要打开就淹没在文件列表里。先看包结构。Spring Boot项目最经典的层次是src/main/java/com/example/shop/ ├── controller/ // 控制器层接收请求返回页面或JSON ├── service/ // 业务接口 │ └── impl/ // 业务实现 ├── mapper/ // MyBatis-Plus 数据访问接口 ├── entity/ // 实体类对应数据表 ├── config/ // 配置类分页插件、拦截器、文件上传配置 ├── common/ // 公共返回结果、异常处理、常量类 └── ShopApplication.java // 启动类阅读顺序我建议先看启动类和pom.xml了解项目引入了哪些依赖。看application.yml了解端口、数据库配置。看entity了解每个表映射的字段。看mapper了解有哪些数据查询方法。看service实现类业务逻辑都在这里比如下单、支付、购物车操作。看controller了解哪些URL对应哪些页面和JSON接口。最后回到前端templates和static目录把URL和页面串联起来。这样读一遍基本就能在脑子里画出系统运行的地图了。碰到看不懂的地方先在IDE里搜索方法名把调用链从头捋到尾比如addCart这个URL从controller入口开始一步步走到SQL语句整个流程就通了。4.3 常见的个性化改造思路如果不想只改个名字就交上去我建议在原有系统上做1到2个低成本高显示的改造。这里说三个最推荐的给商品列表页加搜索历史或排序筛选比如按价格升序/降序。代码改动不大只要在查询wrapper里根据参数动态orderBy前端加两个链接即可。这样功能上多了一个“用户可选排序”文档里也可以多写一个小节。给后台加一个“促销活动”的折扣字段比如商品表增加discount字段下单时实际支付金额乘以折扣。实现上并不复杂核心是查询商品时读出折扣计算pay_amount时再利用BigDecimal计算。虽然业务简单但“满减/折扣”是在电商系统里很常见的概念答辩时有话题可聊。把支付改成模拟支付。很多课程设计项目会把“支付”做成一个状态直接改变但这看起来太业余。更合理的做法是增加一个支付确认页用户提交订单后跳到确认页点击“确认支付”后模拟第三方支付平台回调再更新订单状态。哪怕不真的对接第三方只要逻辑上分成“生成支付请求”和“处理支付回调”两步系统设计的层次立刻提升。无论怎么改造都要记住不要动核心表结构。新增字段可以重构订单表非常危险很可能牵一发动全身最后把自己绕进去。5. 万字文档与答辩准备把“做了系统”变成“讲清系统”5.1 课程设计文档的标准骨架“附万字文档”听起来吓人其实很好拆。课程设计文档通常有固定套路做一个电商系统的文档基本是七部分中文摘要和英文摘要。摘要写清楚系统背景、开发技术、实现功能、结论300到500字。英文摘要不要直接机翻至少把句式调通顺。第一章绪论。写项目背景、国内外研究现状、开发目的和意义。这个章节理论性最强可以引用几篇知网论文不要通篇编。第二章需求分析。先写系统角色、业务流程再列功能需求。建议用表格列功能模块比如用户管理、商品浏览、购物车管理、订单管理、后台管理。非功能需求也要写包括性能要求、安全性、响应时间。第三章相关技术介绍。讲Spring Boot、MyBatis-Plus、Thymeleaf、MySQL。技术介绍里不要照抄官方文档要结合本项目说明“为什么选择它”。这一段是凑字数神器但也是最容易堆废话的地方。第四章系统设计。包括总体架构设计、功能模块设计、数据库设计。数据库设计一定要放E-R图和表结构说明。这几个图表是文档的灵魂。第五章系统实现。按模块讲解实现思路配核心代码片段和运行截图。代码不要全贴挑关键的比如下单事务、分页查询、支付回调。第六章系统测试。写测试环境、功能测试用例表、部分性能测试结果。测试用例表用表格写编号、测试模块、操作步骤、预期结果、实际结果、是否通过。第七章总结与展望。写这段时间做了什么遇到的问题和解决过程还可以写未来的改进方向比如“引入Redis做缓存”或“采用H5商城”。为什么能到万字因为每个模块展开写加上代码段、截图、表格、图表之后一万字其实轻松就能到。真正要警惕的是注水注得太明显比如技术介绍写了两千字跟项目毫无关系老师一眼就看穿。5.2 从源码和数据库里提炼图表素材文档里最吸引老师眼球的不是文字而是图。我见过的优秀文档至少包含四类图系统用例图。用椭圆表示角色用例用方块表示系统边界。用户端用例注册、登录、浏览商品、加入购物车、下单、支付、查询订单管理员用例商品管理、订单管理、用户管理、统计报表。工具推荐ProcessOn或者Draw.io几分钟就能画完。E-R图。核心实体用户、商品、分类、购物车、订单、订单明细、收货地址。连线标好1对N关系。画E-R图时不要直接放数据库表里的字段列表截图那叫表结构截图不叫E-R图很多同学在这上面吃亏。业务流程图。至少两张一张是用户从加入购物车到下单支付的流程图另一张是管理员处理订单的流程图。流程图画清楚代码逻辑才显得有支撑。系统架构图。用三层架构展示层Thymeleaf页面、业务层Controller/Service、数据层MyBatis-Plus/MySQL。这张图要放在系统设计章节表示你已经具备全局架构意识。运行截图不要截图截得太黑太模糊。统一浏览器窗口大小尽量把当前操作的对象放在截图中间。一张截图配两行说明文字解释图上展示的业务。5.3 答辩高频问题与回答方法答辩时间通常五到十分钟。老师不关心你代码里有了多少行他们喜欢问原理和“为什么”。我把高频问题整理成列表你可以提前准备为什么选用Spring Boot回答思路简化配置、内嵌Tomcat、自动装配、生态成熟一句话总结就是“能快速搭建可运行的独立Web项目”。MyBatis-Plus和MyBatis的区别是什么回答思路MyBatis-Plus是MyBatis的增强工具内置通用Mapper、通用Service、分页插件和条件构造器开发单表CRUD效率高复杂多表SQL仍然可以用XML实现。项目中事务是怎么实现的回答时直接讲下单代码把Transactional注解、开启事务后多个SQL要么全部成功要么全部回滚这个原理说清楚。库存超卖问题怎么解决用我之前提到的update语句回答说明数据库层面的原子性更新能防止并发下库存扣成负数。你说一下登录状态是怎么保持的回答思路用户登录成功后将user对象放入session拦截器在处理请求前检查session中是否存在用户信息不存在则重定向到登录页。如果项目用的是JWT就改成分析token的生成和校验流程。系统如何防止SQL注入回答思路MyBatis使用预编译#{}占位符底层是PreparedStatement参数化查询搜索关键词时禁止直接拼接字符串。如果你了解MyBatis-Plus的条件构造器可以顺着讲一句“条件构造器也会自动使用预编译”。这五个问题如果能不看稿子自然回答出来答辩基本稳了。切记不要背书式地回答哪怕答得不太完美只要用“自己的话”讲出逻辑老师都会认可。6. 常见问题与避坑实录6.1 环境与启动问题我见过最多的问题是项目跑不起来症状五花八门。总结下来就是三类第一类IDEA里一堆飘红所有import报错依赖没下载成功。解决方法是配置Maven镜像后reimport还不行就把本地仓库里对应的目录删掉再重新下载。第二类启动报错说“Invalid bound statement (not found)”。这是MyBatis的MapperXML没有被扫描。看看启动类上有没有加MapperScan或者每个Mapper接口上有没有加Mapper注解。还有可能是XML文件没有放在resources里的正确目录导致target目录里根本没编译进去。第三类启动提示数据库连接失败。原因绝大多数是application.yml里的url、用户名、密码写错或者MySQL服务没启动或者本地MySQL端口不是3306。遇到先ping通云服务器本地就不需要ping了直接用Navicat连一下数据库能连上再启动项目。6.2 数据库连接与中文乱码数据库中文乱码有两个位置。第一是项目连接数据库的字符集不对。在JDBC URL中要配置jdbc:mysql://localhost:3306/electronic_shop?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseUnicodetrue和characterEncodingutf8保证写入读取都按UTF-8处理serverTimezone解决MySQL 8.0的时区报错。如果你用MySQL 5.7serverTimezone可以不加但加上也没问题。第二个位置是MySQL表本身的字符集。建库时建议指定CREATE DATABASE electronic_shop DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;utf8mb4比utf8能存更多字符表情符号或者“双十二”这类特殊文字都不会出问题。还有一个小问题图片上传到本地目录后页面上显示的是乱码或找不到图片。这通常是因为Spring Boot默认不把本地磁盘某个目录映射成静态资源。需要写一个配置类把上传目录通过ResourceHandler注册进去public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceHandler(file: uploadDir /); }早年间在没有系统学Spring Boot的时候很多学生会把图片路径写成“D:/upload/xx.jpg”浏览器直接访问当然拿不到。用这种方式图片访问路径就是http://localhost:8080/upload/xx.jpg页面模板里也能正常显示。6.3 前端页面与拦截器配置页面显示404是最容易让人崩溃的事。静态资源404记得检查拦截器有没有放行/static/路径模板页面404大概率是templates下的页面文件路径和controller返回的视图名对不上。Spring Boot默认从classpath:/templates/下解析Thymeleaf模板controller返回“index”对应的是templates/index.html不要自作聪明在返回值前加“/”。页面能打开但接口返回JSON出错优先看浏览器F12控制台报什么错。最常见的错误是Whitelabel Error Page或者 500异常。这时候看后端IDE控制台里的完整堆栈按提示排查不要瞎改。很多同学一看到报错就清空重来这是最浪费时间的。学会看堆栈信息是从“搬运代码”到“调试代码”的分水岭。还有一个经典问题访问后台管理页面明明管理员已经登录但一刷新就又跳回登录页。这个要查Session和拦截器放行路径。后台管理页面要校验的是管理员权限不能只校验用户是否登录两者要区分开。如果你用一个拦截器同时处理两种逻辑一定要在session中同时保存用户角色并在拦截器里判断role。6.4 给自己留出“能讲出来”的时间文章写到这里已经很长了所有技术细节其实都是为了最后一句话课程设计和毕业设计最终要过的是答辩而答辩考的是你对项目的理解。很多同学拿到源码之后“三天新鲜劲”跑起来能点截图截了文档交了就觉得自己完成了。结果老师问“这里为什么加事务”答不上来场面非常尴尬。我的建议是在设计完成前把系统从头到尾跑两遍以上每次自己给自己讲一遍先是用户视角从注册登录到下单支付边点边讲每一步发生了什么然后是开发者视角打开源码对着核心方法讲出SQL执行过程。讲不出来的地方就是你需要补课的地方。这比多改代码更能提升答辩通过率。如果你手头刚好有这套系统的源码和数据库脚本最后再分享一个我亲测有效的做法把核心表的字段和功能模块的对应关系列成一张表格然后对着表格把每个模块的请求路径、Controller方法名、Service方法名、Mapper方法名串联起来。这套体系你能自己写出来比任何背书都管用。这两年我带过的学生里凡是肯花一个晚上做这个梳理的答辩没有翻过车。