ARTICLE DETAIL

建站实战干货

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

电商练习Demo从零搭建:核心链路、库存扣减与踩坑实战

2026/9/8 7:14:11 拓冰建站 浏览量
电商练习Demo从零搭建:核心链路、库存扣减与踩坑实战 简介电商项目练习demo是一份面向电商开发学习者的完整示例项目覆盖从用户、商品、订单、支付到物流、推荐等核心业务链路既能帮助新手建立电商系统整体认知也可供有经验的开发者对照复盘架构设计与技术选型。压缩包共1024个文件以949张PNG界面截图与流程图为主另有53张JPG素材、16个Markdown说明文档、5个GIF动态效果及1个HTML页面整体仅55.21MB便于下载后按目录翻阅。包内对前端React/Vue、后端Spring Boot/Django、数据库设计、JWT身份验证、Redis缓存、支付与物流API集成、安全防护、性能优化及自动化部署等十大要点均有涉及并配有大量截图与动图演示实际页面和交互流程。已有723人学习适合在课余或实训中作为电商项目练手素材快速理解模块划分并延伸出自己的毕业设计或业务原型。 电商项目练习demo这种工程听起来不像大系统那么唬人但的的确确是检验后端功底和工程习惯的好地方。我前前后后写过好几个类似的项目从最开始的纯Servlet版到Spring Boot Vue再到后面加了Docker编排每个阶段都能从这套demo里学到新东西。有些人觉得练习项目就是“能跑就行”但我更愿意把它当成一个沙盒在这里试错成本低可以把商品的增删改查、购物车、订单流转、库存扣减这些电商核心链路完整走一遍。这篇笔记我就用自己踩过的坑聊聊怎么把一个电商练习demo做得既完整、又能真正成为面试谈资。1. 先想清楚这个电商demo到底要练什么1.1 功能边界比功能数量更重要很多初学者做练习项目容易陷入“功能越多越好”的误区。我见过有人给demo硬塞秒杀、优惠券、直播带货、分销裂变结果做了一半就烂尾。其实一个合格的电商练习demo应该先把最经典的闭环做完整用户登录、商品列表、商品详情、购物车、创建订单、库存扣减、模拟支付、订单状态流转。这几件事跑通了你对电商系统核心数据流的理解已经能覆盖大多数初级岗位的面试问题。那后台管理要加吗我的建议是“可以做但不是第一优先级”。练习demo的核心价值在于让你把一条核心链路吃透而不是把整个电商平台复刻一遍。你可以在纸上先画出用例图普通用户能做什么、可选的管理员能做什么再根据用例去定义接口。这一步看似很简单但真的能帮你避免“首页还没做好就跑去改数据库表结构”这种情况。我个人的经验是先把用户端走通再往后端补一个简单的商品管理接口用于验证“一个商品如何从入库到被下单”这个顺序最顺。1.2 技术栈选择的真实理由技术栈怎么选完全取决于你的练习目标没有标准答案。如果目标是快速验证前后端协作、把简历里的“全栈项目”坐实Spring Boot Vue或React是最省事的组合生态成熟、网上资料多遇到问题基本都能搜到答案。如果目标是学习移动端Android Kotlin Compose 本地Mock数据也可以做成一个demo但你要清楚它和后端联调的成本。如果目标是App加服务端完整跑通那后端接口一定要先定义好移动端再用Retrofit或Ktor去调用。我自己比较推荐“主语言 最简数据库 一个缓存/队列”的起步组合。什么意思主语言选你找工作最想用的数据库用MySQL缓存可以后加消息队列可以只在本机用Docker跑一个简单的别一上来就上微服务、上K8s。把链路跑通再逐步加复杂度这样每一步你都清楚它解决了什么问题而不是为了技术而技术。2. 从零搭起一套可运行的电商demo2.1 目录结构与工程初始化工程初始化这一步看似简单但目录结构是否清晰直接决定你后续几天写代码的心情。我建议采用前后端分离整个仓库目录大致可以这样划分shop-demo/ ├── backend/ // Spring Boot服务 ├── web/ // Vue/React前端 ├── app/ // 可选移动端或桌面端 ├── doc/ // SQL脚本、接口文档、演示截图 └── README.md后端工程建议从官方初始化器或Maven骨架创建groupId用com.example就行artifact命名成shop-demo-backend。前端如果选Vite直接运行创建命令就能拿到一个干净的基础工程。这里有一个我反复踩过的坑前后端不要放在同一个Spring Boot静态资源目录下硬揉会让部署和排查都很难受。前后端独立目录各跑各的端口联调的时候通过CORS或代理解决跨域思路会清晰很多。初始化的第一件事不是写代码而是确认前后端基础工程都能“空跑”起来。前端启动后能看到Vite欢迎页后端启动后/actuator/health能返回UP这一步做好了后面所有联调问题都更容易定位。2.2 数据模型设计电商的核心是“关系”电商业务的数据模型非常典型练习项目不需要设计几十张表但核心的表结构必须符合业务直觉。我推荐一份最小可用的表设计表名核心字段作用userid、username、password、nickname用户认证信息productid、title、cover_url、price、stock、status商品主数据cart_itemid、user_id、product_id、quantity购物车明细ordersid、order_no、user_id、total_amount、status、created_at订单主表order_itemid、order_id、product_id、product_title、product_price、quantity订单快照明细注意order_item里要把商品标题和价格冗余进去因为商品信息可能随时被改动但订单一旦生成这笔交易的商品名称和成交价就应该固定下来。这是电商设计里一个很容易被忽略的点也是面试经常喜欢问的“为什么订单明细要存快照”的原因。数据库初始化我建议准备两份SQLschema.sql负责建表data.sql负责插入一些测试商品。Spring Boot整合MySQL时记得配置spring.sql.init.modealways这样每次启动都会执行初始化脚本省去手动导入的麻烦。当然生产环境不能这么干但练习阶段简直是提效利器。2.3 后端接口设计思路接口设计不要照搬大公司的文档风格练习项目最重要的是“面向使用场景”。前端页面需要什么数据后端就提供什么接口先让闭环能跑再考虑RESTful标准。我常用的接口清单POST /api/user/login登录返回用户信息基础数据GET /api/product/list?page1size10分页获取商品列表GET /api/product/{id}商品详情POST /api/cart/add加入购物车GET /api/cart查看购物车POST /api/cart/clear清空购物车POST /api/order/create创建订单POST /api/order/pay/{orderNo}模拟支付GET /api/order/{orderNo}查询订单状态这里有一个细节接口路径里的动词用login、pay这类业务动作是可接受的因为它们是业务语义但增删改查尽量用HTTP方法表达比如POST /api/cart/add和POST /api/order/create很多规范党会觉得冗余但练习阶段这样写直白、不容易搞混后续再慢慢做REST化也不迟。2.4 前端页面与交互闭环Web端页面控制在5个以内商品列表页、商品详情页、购物车页、结算页、订单结果页。过多的花哨页面会消耗你的精力却对核心链路没帮助。前端技术细节上如果用了Vue推荐用Pinia管理购物车状态如果用了React就用Redux Toolkit或Zustand。购物车交互要做到“本地状态即时更新、后端持久化兜底”加购时先更新前端store同时调后端接口接口成功则返回最新购物车列表并整体替换失败则回滚本地状态并且弹出提示。这样能避免用户在多个浏览器标签页操作时出现数据不一致。还有一个前后端联调的小心得字段命名两端一定要统一。前端用cartNum后端用count这种看着不起眼的问题调试起来会比业务逻辑bug更浪费时间。我第一次做demo时就在这上面卡了两个小时。3. 核心链路实操从商品列表到订单支付3.1 商品列表与详情商品列表接口不要上来就select *至少要有分页参数并且支持按关键词模糊搜索和按上下架状态过滤。对应的SQL大致是SELECT * FROM product WHERE status 1 AND title LIKE CONCAT(%, #{keyword}, %) ORDER BY created_at DESC LIMIT #{offset}, #{size}前端拿到列表后点击某个商品进入详情页详情页再调/api/product/{id}获取完整信息。图片字段建议存URL字符串不要存base64否则数据库会脏、接口也会变得很慢。这个细节对练习demo而言更重要它能帮助你理解“文件服务”和“业务服务”为什么要分开至于实际部署时用OSS还是本地静态目录都是后续扩展的事。3.2 购物车状态管理购物车是前端状态交互的重头戏。一个商品可能已经被加入购物车此时加购按钮应该显示“去结算”而不是“加入购物车”。这个状态需要由前端根据购物车数据自行判断后端不需要额外提供“是否已加购”的接口。如果做跨端复用购物车接口一定要设计成“按用户维度存取”而不是把购物车数据只存在前端localStorage里。否则你在手机端加购的东西网页端根本看不到就失去了电商的核心体验。练习项目可以前后端都做本地store覆盖即时交互后端接口覆盖数据持久化刷新页面后从后端拉取恢复。3.3 下单与库存扣减创建订单是整个demo里技术含量最高的地方也是面试最容易追着问的点。核心逻辑是在同一个事务里完成“检查库存、扣减库存、创建订单、创建订单明细”。最稳妥的做法是用数据库行锁或乐观锁。我先说推荐写法一句带条件的update语句完成原子扣减UPDATE product SET stock stock - #{quantity} WHERE id #{id} AND stock #{quantity}如果这条语句返回的影响行数为1说明库存扣减成功返回0说明库存不足或商品已下架需要抛出异常并回滚整个事务。为什么推荐这个写法因为它把“判断库存是否充足”和“扣减库存”合并成了一步避免了“先查再用”导致的并发超卖问题。练习阶段用这个方案完全够用也足够解释清楚原理。如果要更进一步可以在product表增加一个version字段用乐观锁控制并发但逻辑会稍微复杂。我第一次跑并发测试时用JMeter模拟100个并发请求下单同一件库存为20的商品使用上面的update方案后最终只成功了20单库存正好归零这个结果让我对“原子操作”有了非常直观的理解。3.4 模拟支付与订单状态机真实项目对接支付网关很复杂但练习demo只需要一个“模拟支付成功”的接口就能闭环。我的做法是在订单详情页放一个“确认支付”按钮点击后后端直接更新订单状态并在pay_log表里插入一条支付流水。订单状态可以用一个int字段表示也可以用字符串枚举我推荐用字符串因为阅读起来更友好比如INIT、PAID、CANCELLED、SHIPPED。状态流转逻辑一定要清晰用户创建订单后状态为INIT也就是待支付用户模拟支付成功状态变为PAID如果超过一段时间未支付状态可以由一个定时任务改为CANCELLED发货后状态变为SHIPPED练习项目里至少要把前两个状态流转做扎实后面两个可以留作扩展。状态机这个概念听起来很高深但落到电商订单上就是“不同状态下允许执行哪些操作”把规则定义清楚后面加购物优惠、退款流程都会轻松很多。4. 常见问题与排查技巧实录4.1 跨域、端口占用、接口404电商demo前后端分离后每天都要面对这几个问题。跨域是最常见的前端跑在5173后端跑在8080不配置CORS的话浏览器会直接拦截。解决办法很简单后端的配置类里加一个全局CORS配置允许所有来源、所有方法或者在前端开发服务器里配置proxy把/api代理到http://localhost:8080。我推荐用后者因为生产环境部署时通常也会有类似的网关转发逻辑。端口占用也很好排查启动后端显示Port 8080 was already in use多半是之前启动的进程没杀干净。在Linux/Mac上用lsof -i :8080Windows上用netstat -ano | findstr 8080把对应进程关掉就好。接口404基本都是路径写错了特别是RequestMapping(/api)这种类级别的注解配合GetMapping(/product/list)双重路径很容易拼错。遇到404别急着改代码先开浏览器的Network面板看实际请求的URL和后端Controller路径是否完全一致。4.2 数据库连接与初始化数据加载失败“数据库连不上”是新手遇到最多的拦路虎。现象通常是应用启动时报Access denied for user rootlocalhost。排查时先确认MySQL服务启动了没再确认配置文件里的用户名密码对不对最后检查时区配置建议在JDBC URL里加上serverTimezoneAsia/Shanghai。还有一次我在练习项目的fetch步骤遇到了无法下载依赖的问题报错信息各种各样后来发现是Maven本地仓库缓存坏了。先删掉本地仓库中对应组件目录重新构建一般都能解决。另外数据导入失败通常是因为SQL脚本里混了MySQL 8新增语法而本地却是5.7务必保证数据库版本和依赖版本对应得上。4.3 并发下单导致的库存超卖“假象”如果你用JMeter压测时发现库存变成了负数先不要觉得是数据库不够强多半是代码逻辑问题。典型错误是先查询库存判断大于0再执行更新SELECT stock FROM product WHERE id #{id}; -- 在代码里判断 stock 0 UPDATE product SET stock stock - 1 WHERE id #{id};这两条SQL一旦被并发执行查询时都看到还有库存更新时也都会成功超卖就发生了。上一节我写的UPDATE ... WHERE stock #{quantity}就能解决这个问题。还有一个小技巧压测时如果MySQL事务隔离级别比较高可能会遇到锁等待超时不用太紧张降低一下并发线程数先把业务跑通。4.4 专项踩坑构建打包时遇到的“non-resolvable parent pom”问题热词里有一条project build error: non-resolvable parent pom for com.example:demo:0.0.1-sn我看到这个描述特别有共鸣因为我在练习demo时就踩过一次。这个报错的意思是当前模块声明的父POM在Maven仓库里找不到。排查主要看三个地方父工程的groupId、artifactId、version是否和实际一致尤其在多模块工程里子模块的parent坐标写错一个字母都找不到。本地仓库中是否真的缓存了对应版本可以在~/.m2/repository/com/example/...目录下看有没有对应的.pom文件。如果父POM也是自己写的子模块需要能通过relativePath找到父模块目录默认是../pom.xml目录结构变了就会出问题。我当时的解决方案是删掉本地仓库里那一整个com/example目录然后重新执行Maven构建让它重新拉取。经验教训是练习项目尽可能不要自己手写复杂多模块POM直接用Spring Boot官方父依赖就能覆盖大部分需求少折腾、少踩坑。5. 扩展方向让练习demo变成面试谈资5.1 微服务拆分与容器化单体demo跑通后可以尝试把用户、商品、订单三个模块拆成独立服务。拆分前先想清楚一个关键问题购物车和商品详情的联调怎么办我是用最简单的Spring Cloud OpenFeign做服务间调用不用太复杂只要让order-service能调用product-service的接口完成库存扣减即可。容器化是另一个高性价比扩展方向。写一个Dockerfile把后端打成镜像再用docker-compose.yml把MySQL和Redis一起编排起来。这一套做完你对“环境一致”“一键部署”的理解会非常深刻。值得注意的是不要在练习阶段就上K8s成本高、排错难很容易打击信心。5.2 从Web端到鸿蒙端/安卓端的demo迁移同一个后端API其实可以很轻松复用到多个端。我后来就把这套电商demo的后端接口在一款Android Kotlin Compose的练习工程里调用了一遍发现只要后端接口参数稳定移动端代码写起来比想象中顺手。如果要做鸿蒙的练习demo要注意它的工程产物可以打包成HAP、HSP、HAR三种格式分别对应应用包、共享包和静态共享包。你在练习阶段不用太纠结这些产物格式的具体差异只需要理解“后端接口是数据来源不同端负责不同展示和交互”即可。多端复用的价值在于它让你明白分层设计为什么重要数据层、业务层、展示层的边界一旦清晰换端损耗就会很低。5.3 从电商demo到MCP服务demo的延展最近很多人在聊MCP也就是Model Context Protocol简单地把它理解为“让外部工具能力标准化地接入到AI应用”的一种协议。如果你已经有一个电商demo的商品接口完全可以照着MCP的规范把它封装成一个服务demo让AI助手可以直接调用你的商品查询、订单创建等能力。这是一个很有意思的延伸玩法能让你同时拥有传统Web开发和AI应用开发的交叉视角。但我的建议是这个扩展适合在主流程已经很熟练之后再加。先学会走再去跑。把电商核心闭环做扎实后面的扩展都是锦上添花。我做了很多次demo之后最大的体会是练习项目的价值不在于页面有多漂亮、接口数量有多惊人而在于你有没有把一个闭环跑通并且知道每个环节为什么这么做。如果你现在正准备做电商练习demo不用贪多把商品、购物车、订单和支付这四个模块做扎实然后把打包、部署、写接口文档这些事也顺手做一遍收获会比想象中大得多。最后一个小建议demo一定要提交到Git仓库每次扩展功能前都留一个可运行的tag这样你改坏了也不怕回不去。本文还有配套的精品资源点击获取