搞Java后端的同学应该都有这种体验项目源码网上能找到不少但能完整跑通的不多带文档的更少带文档还能做到前后端分离、技术栈不过时的就少之又少了。这套网上宠物店系统属于少数能让我本地几分钟内就启动起来的项目。SpringBoot2 Vue3 MyBatis-Plus MySQL8.0四个关键词直接命中当前主流的Java Web开发组合。整套源码整理得很规整附带SQL脚本、接口文档、设计说明不管是拿来当毕设参考、自己练手还是想二次开发做点小生意都有文章可做。这篇文章我不做源码逐行讲解而是把整个项目拆开揉碎从架构设计、数据库建模、后端核心实现、前端要点、部署排错到扩展方向完整地过一遍。1. 项目定位与整体架构拆解1.1 这套系统到底包含哪些功能宠物店系统听起来简单实际拆开来看涉及到的业务模块并不少。这套系统从前台用户视角和后台管理员视角分别设计了两套界面。用户端核心功能注册登录基于JWT做无状态认证退出登录前端清除token即可商品浏览按宠物类别分类展示支持关键词搜索商品详情包含轮播图、价格、库存、描述信息购物车管理加购、改数量、删除、批量结算订单提交与查询我的订单列表、订单状态流转个人中心收货地址管理、个人信息修改后台管理端核心功能管理员登录与权限拦截宠物商品管理商品的增删改查上下架操作类目管理对宠物分类进行维护轮播图管理配置首页展示的Banner订单管理查看所有订单修改订单状态用户管理查看注册用户信息整体看下来这是一套标准的电商系统教学实战项目。业务完整度比单纯增删改查Demo高出一个级别又没有大型电商系统那些复杂的分销、优惠券、秒杀逻辑作为学习模板刚好合适。1.2 前后端分离架构速览项目整体是典型的前后端分离结构端口也做了区分。后端SpringBoot默认跑在8080端口前端Vue3开发环境下通过Vite代理到后端接口避免跨域问题。交互链路大致是这样前端Vue页面通过axios发起HTTP请求请求先经过后端拦截器校验JWT是否有效通过后进入Controller层再向下调用Service层处理业务逻辑Service层通过MyBatis-Plus操作MySQL数据处理结果封装成统一的JSON结构返回给前端前端根据响应状态码做对应处理渲染页面我比较欣赏的是它没有把后端代码全堆在Controller里。很多新手项目习惯把业务逻辑直接写在Controller方法里这套项目至少分出了Controller、Service、Mapper三层代码结构上具备可读性也方便后面做扩展。前端目录结构和后端对应按页面维度拆分了views目录公共组件放在components里接口请求统一放在api目录。我在实际翻阅源码时最大的感受是命名规范统一驼峰、语义化都做得不错不需要花太多时间就能定位到某个功能对应的代码位置。2. 技术选型背后的取舍逻辑2.1 后端SpringBoot2并非越新越好很多人在选型时会纠结用SpringBoot2还是3.x。这套项目选择SpringBoot2.x是经过考量的。SpringBoot3要求JDK17起步而不少高校实验室和生产环境的机器还停留在JDK8。SpringBoot2.x配合JDK8是当前存量最大的组合资料多、踩坑记录多、出了问题好搜解答。从学习到工作的平滑过渡角度看SpringBoot2其实是更稳妥的选择。配合的MyBatis-Plus也有讲究。相比原生MyBatis需要手写大量XMLMyBatis-Plus提供了BaseMapper通用方法单表CRUD几乎不用写SQL。宠物店这种业务量级的系统大部分操作都是单表查询多表关联场景很有限用MyBatis-Plus能把开发效率提上来。而且它的分页插件、条件构造器对新手非常友好代码写起来直观。2.2 前端Vue3组合式API带来的开发体验前端选择了Vue3这已经是当前前端框架的主流方向。项目里采用的是组合式API风格用setup语法糖写组件。相比Vue2选项式API组合式API在逻辑复用上明显更灵活。管理后台的表格、表单、弹窗等组件基本都是研读Element Plus的官方文档后封装出来的。我对这套技术组合的评价是没有引入全家桶式的重量级框架也没有追求CSS框架的花哨效果组件化程度作为学习型项目完全够用且代码简单好懂适合新手去读。2.3 数据库MySQL8.0的默认选择MySQL8.0在性能和功能上都比5.7强窗口函数、公共表表达式这些特性在复杂统计查询里很好用。现在新安装的MySQL基本都是8.0版本项目直接使用8.0避免了很多旧版本兼容问题。值得一提的是8.0的默认身份认证插件是caching_sha2_passwordJDBC驱动需要匹配后面部署环节我会专门说这个坑。在本地开发时一般建议装Navicat或者DataGrip来管理数据库。直接导入项目提供的SQL脚本就能建库建表非常省事。记得提前确认字符集建库时用utf8mb4别用utf8否则存emoji或者生僻字容易出乱码。3. 数据库设计七张核心表如何支撑一个电商闭环3.1 用户表和购物车的拆分思路用户表users设计得比较收敛字段基本是id、username、password、phone、email、avatar这类常规信息。密码存储没有明文保存走的是MD5加盐的思路安全性上比纯明文好很多。这里有一个设计细节我特意看了购物车单独建了cart表字段包含用户id、商品id、数量、选中状态。为什么不直接把购物车商品放到订单里因为购物车是用户的临时挂单区它不产生业务数据变化用户很久没下单购物车内容还在订单则是交易凭证包含的是商品快照。两者拆开后续做订单统计和商品销量分析时数据边界清晰很多。3.2 商品表与类目表的关联设计商品表pet在命名上做得比较讨巧直接用业务词汇做表名。字段设计包括商品名称、原价、现价、库存、图片、所属类目、销量、描述、上架状态。类目表category单独拆出来跟商品表通过category_id关联。这种设计的好处是类目可以灵活增删比如新增一个小宠用品类目不需要改动商品表结构。从代码层面看列表页请求接口时前端传入categoryId后端用MyBatis-Plus的QueryWrapper做条件查询一行条件构造就完成过滤性能和写法都很轻量。商品图片字段存的是URL路径实际使用中图片资源可以放在本地静态目录也可以接入对象存储。这种设计天然兼容了不同规模的部署方式。3.3 订单相关表的状态流转设计订单模块是整个系统的核心涉及order订单主表和order_items订单明细表。订单主表存订单编号、用户id、总金额、收货人信息、订单状态、创建时间明细表存商品名、商品图片、购买数量、购买单价。为什么要拆主表和明细表一个订单可能包含多种宠物用品主表存订单维度信息明细表存商品维度信息这样无论按订单查总金额还是按商品统计销量都不需要跨表扫数据。订单状态用数字类型存储含义通过代码注释说明。我建议拿到源码后先全局搜一下订单状态对应的常量映射把0待付款、1已付款待发货、2已发货、3已完成、4已取消这些数字含义标在笔记里后面调试时能省不少时间。4. 后端核心代码实现复盘4.1 统一响应结构与全局异常的实战处理这可能是整套代码里最值得学习的一部分。项目封装了统一的响应体结构大概长这样{ code: 200, message: 操作成功, data: { ... } }Controller层不需要手动拼装返回结果业务方法只负责返回数据统一由Result工具类包装。这么做最大的好处是前端处理逻辑统一axios拦截器里判断code字段是否为200是就取data渲染否则弹出message提示。如果每个接口返回结构都不一样前端每个请求都要单独写处理逻辑维护成本成倍上涨。全局异常处理也值得说。项目里用RestControllerAdvice统一捕获业务异常和未预期异常而不是在每个Controller里try-catch。这样代码干净得多即使遇到空指针这类意外错误用户端也只会收到一个友好提示不会把异常堆栈暴露给前端。4.2 JWT登录认证与前端token联动登录流程很常规但很完整。用户提交用户名密码后后端校验通过生成JWT令牌返回前端。前端拿到token后存储在本地通常是localStorage之后每个请求在请求拦截器中把token塞进请求头。后端侧需要重点理解的是拦截器配置Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtInterceptor) .addPathPatterns(/api/**) .excludePathPatterns(/api/user/login, /api/user/register, /api/commodity/**); }拦截器要从请求头中解析token校验合法性然后把用户信息放入请求上下文。这里有个实战细节拦截器只拦截需要登录的接口像商品列表、商品详情这种公开接口要注意排除在外否则用户没登录连商品都看不了。我自己写项目时经常在这个配置上踩坑。4.3 MyBatis-Plus的三个高频写法项目里MyBatis-Plus的用法非常典型掌握了这三处就相当于掌握了它八成用法。第一个是IService和ServiceImpl的配合。业务Service继承IService接口实现类继承ServiceImpl所有通用方法直接继承下来比如查询列表的list()、按id查询的getById()、分页的page()。第二个是QueryWrapper条件构造器。例如商品分页查询QueryWrapperPet wrapper new QueryWrapper(); wrapper.like(StringUtils.isNotBlank(name), name, name) .eq(categoryId ! null, category_id, categoryId) .eq(status, 1); PagePet page petMapper.selectPage(new Page(current, size), wrapper);这个写法有几个好处。第一个参数传入布尔值控制条件是否生效前端没传搜索关键词时like条件自动跳过避免拼出空条件的查询同时静态方法调用很安全不会出现字符串拼接的SQL注入问题。第三个是分页插件的配置。MyBatis-Plus的分页依赖PaginationInnerInterceptor插件需要在配置类中注册Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; }忘记配这个插件分页方法会查出全量数据这是新手最容易踩的坑。项目里已经配好了但我建议你自己动手删掉再跑一遍分页观察现象理解原理远比背配置重要。4.4 订单提交的事务处理提交订单这个操作涉及多张表的数据变更生成订单主记录、写入订单明细、扣减商品库存、清空购物车中对应商品。这一系列操作要么全部成功要么全部失败必须开启事务。项目在Service方法上加了Transactional注解来保证原子性。它的原理我简单说下Spring默认对RuntimeException回滚对受检异常不回滚所以如果有业务点在子方法里抛出Exception类型记得在Transactional上声明rollbackFor Exception.class否则会出现订单生成了但库存没扣这种脏数据。这个是经典的隐藏Bug项目里没有这个问题但你二次开发时一定要有这个意识。库存扣减这里还涉及到并发问题。虽然宠物店体量不大但如果上线后几十个人同时下单抢最后一件商品不加锁就可能超卖。我看了源码它没有做库存乐观锁校验这个可以作为你扩展练习的方向用version字段实现乐观锁是MyBatis-Plus非常经典的实战案例。5. 前端Vue3落地实现要点5.1 路由配置和登录守卫前端路由用createRouter创建配合createWebHistory模式。管理端和用户端的路由通过meta信息区分权限。登录守卫的写法是关键router.beforeEach((to, from, next) { const token localStorage.getItem(token); if (to.meta.requiresAuth !token) { next(/login); } else { next(); } });这段代码的逻辑是检查目标路由是否标记了需要登录如果没登录统一跳转到登录页。理解这个机制后你新增页面时只需要在路由配置里加上requiresAuth字段页面立刻受到登录保护扩展起来很舒服。5.2 Axios封装里的拦截器设计前端对请求的统一处理是axios封装。项目里封装了request工具类设置baseURL、超时时间并在请求拦截器和响应拦截器里做token注入和错误处理。请求拦截器service.interceptors.request.use(config { const token localStorage.getItem(token); if (token) { config.headers.Authorization token; } return config; });响应拦截器里判断code完成后端业务状态的统一处理。一个值得留意的点当后端返回401或其他鉴权失败的状态时响应拦截器里最好清除本地token并跳转登录页避免用户一直停留在失效页面里操作然后反复弹错。5.3 商品列表和购物车交互的响应式处理商品列表页通过ref定义数据源onMounted生命周期里调接口拉数据用v-for渲染卡片。搜索和筛选通过绑定事件重新拉取数据实现思路是数据驱动视图。购物车页面有一点值得学习它没有每次操作都请求后端重新拉全量购物车数据而是本地维护一个购物车数组增删改先改本地数据再同步调后端接口。这样页面响应快不闪烁接口失败时回滚本地状态并提示用户。这种乐观更新策略在真实项目里很常用。前端和后端交互时还有一个细节时间格式。后端返回的日期格式默认是带T的ISO格式前端直接显示会很难看。项目里在JSON序列化配置里做了格式化或者前端用dayjs格式化后再渲染。无论用哪种方式统一处理时间格式都是电商类前端页面必须考虑的问题。6. 部署运行与高频报错排查6.1 本地环境准备与启动步骤我把从拿到源码到页面跑通的完整过程列出来照着走基本不会出问题安装JDK8以上版本配置JAVA_HOME环境变量安装MySQL8.0启动服务后在命令行执行项目提供的SQL脚本创建数据库和表结构修改后端application.yml里的数据库用户名、密码和URL确认数据库名一致用Idea导入后端项目等待Maven依赖下载完成启动SpringBoot主类前端项目用VSCode或WebStorm打开执行npm install安装依赖再执行npm run dev启动开发服务器浏览器访问前端地址按文档里的管理员账号登录后台整个过程最容易卡住的环节是Maven依赖下载慢。国内环境下建议在maven的settings.xml中配置阿里云镜像源不然SpringBoot那一堆依赖能下载半小时。同样npm install在默认源下也慢把registry切换成国内镜像体验会好很多。6.2 常见报错速查表我把自己跑项目过程中以及辅导别人跑项目时收集到的高频问题整理成了一张表报错现象根本原因处理办法启动时提示Access denied for user数据库密码配置错误核对application.yml中的用户名密码确认本地MySQL可以登录连接数据库报Public Key Retrieval is not allowedMySQL8.0的caching_sha2_password认证问题JDBC URL加allowPublicKeyRetrievaltrueuseSSLfalse前端接口全部404后端端口不对或没启动成功检查后端控制台日志确认8080端口被正确监听前端请求跨域报错没走Vite代理检查vite.config.js中proxy配置是否正确指向后端地址mybatis-plus分页查询内存溢出分页插件没配置确认MybatisPlusInterceptor已注册登录成功但页面仍在登录界面token未写入请求头检查axios拦截器确认每次请求都携带了Authorization头图片不显示图片路径失效确认上传图片存放的目录与后端静态资源配置路径一致除了这些还有一个容易忽略的问题端口占用。如果本地的8080端口被其他服务占了后端会启动失败。这时可以直接改application.yml里的server.port配置换成8081、8888这些端口前端代理也需要同步调整前端和后端的端口不一致是新手最容易漏掉的地方。6.3 实测过程中的性能观察我把项目在本地跑起来后简单做了下观察接口响应速度基本都在几十毫秒以内日常学习使用完全不存在性能瓶颈。商品列表查询走了MySQL索引返回数据量不大前端渲染也没有明显卡顿。不过如果真要考虑上线有几个点需要注意当前商品图片是静态资源形式存本地单机部署没问题但后续上了云服务器需要把图片目录挂到持久化磁盘或者迁到OSS对象存储后端默认没有配置Redis缓存商品详情这类读多写少的接口可以考虑加一层缓存能显著降低数据库压力。7. 项目学习路径与二次开发方向7.1 拿到源码后的推荐阅读顺序拿到项目后不建议从头到尾按顺序读代码那样容易在细枝末节上迷失。我建议按下面这条路走第一步看数据库脚本搞清楚表结构和表间关系。这一步决定了你对整个业务模型的理解深度。第二步看后端的配置类和拦截器理解项目启动时装配了什么组件、拦截了哪些接口。这一步帮你建立对请求链路的整体认知。第三步挑一条完整业务链路读比如用户浏览商品→加购物车→提交订单从Controller入口往下追到Service和Mapper。跟着一条线走通比零散地看代码更有效。第四步打开前端页面跟着页面操作打断点观察前后端的数据交互。这一步你会把前端组件、API文件和后端接口映射起来整个项目才算真正吃透。第五步找一个功能做微改造。我推荐改造点可以是给商品加一个是否推荐的标记字段连带数据库、后端接口、前端页面全部跑通这个流程走完你基本具备了独立开发类似小系统的能力。7.2 可以扩展的方向建议这套系统的可扩展性不错后续想升级可以从以下几个方向入手接入Redis把首页轮播图和商品分类缓存化体验一下缓存穿透和缓存击穿问题的实际处理方式引入支付回调模拟在订单模块中对接一个支付流程加深对回调、异步通知、订单状态机这些概念的理解增加库存扣减的并发控制用乐观锁解决超卖问题正好补齐当前代码的短板给后台增加数据统计报表基于订单表做月度销量统计这里用上MySQL8.0的窗口函数正好合适部署上云把项目打包部署到一台云服务器上前端用Nginx托管后端以jar包方式运行经历一次完整的线上环境搭建每个方向的工作量都不算大但都能让你对当前这个系统有更深的理解。尤其是并发控制和缓存这两个点面试时被问到的概率非常高自己动手实践一遍比背十篇面经都管用。我个人在实际操作中的体会是这种完整度适中的项目最忌讳的就是把它们当成品代码跑一遍就完事。跑通只是起点真正值钱的是跑通之后你对架构的拆解能力。把数据库表关系画一遍、把请求链路追一遍、把某个功能改造一遍这三件事做完市面上大多数类似的Java Web项目你都能看得懂、改得动。后面再练一个新的前后端分离项目速度会快很多。如果你后续想拿这个项目做二次开发记住一个原则先从改配置和加字段开始不要一上来就动核心的订单逻辑。订单状态流转涉及前端页面、后端接口、数据库状态三端联动改一处忘了另外两处的同步排查起来会非常痛苦。先做加法再做重构风险会可控得多。 SEO 优化官网定制响应式建站教育培训建站