ARTICLE DETAIL

资讯详情

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

SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0宠物商城项目实战全解析

SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0宠物商城项目实战全解析 作为一个常年泡在各种商城系统和前后端项目里的老开发看到“SpringBoot2 Vue3 MyBatis-Plus MySQL8.0”这套组合第一反应就是这几乎是当前Java Web单体应用最主流、最不折腾的黄金搭配了。尤其加上了“含文档”这三个字对刚入行或者正在做毕业设计、课程设计的朋友来说价值一下就上去了。很多同学卡在不是不会写增删改查而是卡在项目结构怎么搭、前端怎么连后端、MySQL8.0的时区问题怎么处理。这个宠物商城项目本质上就是把整套流程走通的一个完整范例从商品浏览、购物车、下单到后台管理覆盖了电商系统最核心的闭环。这篇文章我不打算把它当成一个“演示项目”来泛泛而谈而是会站在一个真正要动手把这个系统跑起来、甚至二次开发的人的视角把技术选型、项目结构、核心模块设计、运行部署的实操步骤以及我会在哪个环节踩坑、怎么排查全部揉碎了讲清楚。不管你是想拿它做课设、写进简历还是纯粹想搞懂Vue3和SpringBoot2到底怎么优雅协作这篇都值得你花十几分钟看完。1. 项目整体设计与技术选型思路先聊点掏心窝的话。很多同学拿到一个项目源码习惯性地先看代码但我建议先看技术选型和目录结构这决定了你后面调试和扩展的时候是“顺着作者的思路走”还是“跟代码搏斗”。1.1 为什么是SpringBoot2 Vue3而不是其他新框架市面上有SpringCloud微服务全家桶也有若依这种带RBAC权限的后台框架但这个宠物商城选了SpringBoot2 Vue3我的理解是它精准地卡在了“适合学习”和“能跑商业项目”之间。SpringBoot2目前在国内企业里的存量极其庞大。虽然SpringBoot3已经发布但很多公司的老项目、中间件兼容性、甚至部分云厂商的文档依旧停留在2.x时代。它上手成本低约定优于配置内嵌Tomcat打一个jar包就能跑。对于课设或者中小型外包项目来说SpringBoot2足够稳定遇到问题网上答案一抓一大把这本身就是效率。Vue3则代表着前端未来的方向。很多人问Vue2用得好好的为什么非要升级Vue3核心原因有三点一是Composition API让复杂组件的逻辑内聚性更强比如购物车状态、商品筛选条件用ref和reactive管理起来比Vue2的data和methods更直观二是TypeScript支持更好虽然很多课设没用上但写进简历能加分三是生态已经成熟Element Plus、Vite这些主力工具都对Vue3做了深度适配。让我用一个生活化的类比SpringBoot2就像一家装修好的毛坯房承重墙、水电管线都给你预埋好了你只需要搬家具进去Vue3则是客厅里的智能家居中枢你可以按自己的心情把灯光、窗帘、音响自由组合联动而不是像Vue2那样想加个功能得去墙上的旧面板里找对应的线路。1.2 MyBatis-Plus如何把CRUD变得“无脑”在这个项目里MyBatis-Plus的价值体现得非常明显。过去我们写一个Mapper要手写大量的insert、select、update标签哪怕只是查个单表也要折腾半天。MyBatis-Plus直接内置了BaseMapper接口里面的selectById、selectList、insert、updateById能覆盖掉大概80%的单表操作。更难得的是它的条件构造器QueryWrapper或LambdaQueryWrapper。比如宠物商城首页需要一个“查找上架状态且库存大于0”的商品列表传统写法是QueryWrapperPet wrapper new QueryWrapper(); wrapper.eq(status, 1).gt(stock, 0); ListPet petList petMapper.selectList(wrapper);如果你用了Lambda版连数据库字段名写错的风险都降低了LambdaQueryWrapperPet wrapper new LambdaQueryWrapper(); wrapper.eq(Pet::getStatus, 1).gt(Pet::getStock, 0);这两个查询语义一模一样但后者在编译期就能检查到字段是否拼错。我特别建议即使项目源码里写的是String版你在二次开发时也要主动改造成Lambda版。这个习惯能让你在后续接手更复杂的系统时少掉很多因为字段名拼写导致空指针或者查不到数据的坑。1.3 MySQL8.0从装环境到参数坑的一次性说明MySQL8.0和5.7最大的感受级区别一个是性能更强一个是默认字符集变成了utf8mb4能直接存表情包字符。但也带来了两个经典问题。第一个是时区问题。你如果用application.yml里的serverTimezoneAsia/Shanghai配置在MySQL8.0以上版本如果驱动版本不匹配会报The server time zone value is unrecognized。我记得最稳的方案是直接在JDBC URL后面拼上serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf8并且把MySQL的全局时区也设置一下set global time_zone 8:00; set time_zone 8:00;第二个是密码加密插件。MySQL8.0默认的caching_sha2_password会让一些老旧的客户端或者Java驱动连不上。如果出现Public Key Retrieval is not allowed你需要在JDBC URL后面再加一个参数allowPublicKeyRetrievaltrue或者干脆在MySQL里把加密插件改回mysql_native_password。我个人的建议是在本地开发环境直接ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码;最省心。2. 核心功能模块与数据表设计拆解看一个商城项目别急着看Controller写了多少行先捋清楚它分了哪几个模块表之间如何关联。毕竟商品、用户、订单这三张大表是商城的命根子。2.1 前后台功能模块划分这个项目按我摸过的同类源码套路一般都拆成两个端面向用户的商城前台和面向管理员的后台管理系统。前台的核心链路是注册登录 → 浏览宠物列表/详情 → 加入购物车 → 提交订单 → 支付模拟→ 查看订单状态。有些项目还会加上收藏、评论、收货地址管理。这一条链路跑通电商C端的核心主流程就完整了。后台的核心链路则是管理员登录 → 商品管理上架/下架/改库存→ 订单管理发货/取消→ 用户管理 → 分类管理。后台界面用Vue3 Element Plus表格加弹窗表单是最常见的组合也是你在做完这个项目之后独立开发一个“后台管理系统”的起步模板。我特别想强调一下通用CRUD服务的写法。我记得有不少开源项目会做一个基于MyBatis-Plus的BaseService内部封装好增删改查逻辑然后让具体的业务Service继承它public class BaseServiceImplM extends BaseMapperT, T extends ServiceImplM, T implements IServiceT { // 直接继承IService就自带save、removeById、page等方法 } Autowired private PetService petService; // 使用示例 boolean success petService.save(pet);这样各模块Service基本不用重复写CRUD逻辑只需要重写个性化业务。你在面试聊项目经验时说出“我基于MyBatis-Plus封装了通用CRUD服务通过Service层继承实现了无状态增删改查大大提升了开发效率”这句话起码比单纯说“我用MyBatis-Plus做了增删改查”要高一个段位。2.2 核心表结构设计好的表结构设计是项目后期不“返工”的基石。以宠物商城为例核心表大概长这样表名主要字段作用pet_categoryid,name,sort宠物分类比如猫、狗、小宠pet_infoid,category_id,name,price,stock,cover_image,status宠物商品信息status字段控制上下架userid,username,password,phone,avatar买家信息密码记得用MD5或BCrypt加密cartid,user_id,pet_id,quantity,checked购物车中间表关联用户和商品orderid,order_number,user_id,total_price,status,create_time订单主表order_number生成一串唯一单号order_itemid,order_id,pet_id,pet_name,price,quantity订单明细表保存下单时的商品快照我在很多开源项目里见过新手常犯的一个错误订单明细里只存了pet_id不存商品名和单价等哪天后台把宠物商品删了订单历史里的商品信息也跟着消失这对电商系统来说是不可接受的。所以你在自己设计时一定要记住“快照”这个词订单明细该冗余的信息必须冗余。2.3 前后端接口交互方式前后端分离项目最核心的是接口约定。Vue3前端通过axios发请求SpringBoot后端暴露RESTful接口返回统一的数据结构。像下面这样{ code: 200, message: 操作成功, data: { records: [], total: 100 } }我建议你把这个统一响应体定义放在后端一个叫Result的类里这也是目前行业里最标准的做法Data public class ResultT { private Integer code; private String message; private T data; }前端封装的request.js里拦截器统一判断code如果是401就跳登录页如果是200就直接返回data给调用方。这个套路已经被验证了无数次你在这个项目里能看到自己在未来任何公司项目里也会用到。千万别每个Controller都返回裸的Map或者List那样前端判断逻辑会想骂人。3. 从零跑通项目环境准备与核心配置实操这部分我按实操步骤来讲每一步后面附上为什么要这么做。照下面走踩坑几率能降到很低。3.1 安装MySQL8.0Windows/macOS/Linux通用思路不管什么系统核心思路都是一样的下载安装包 → 初始化数据目录 → 启动服务 → 设置密码 → 允许远程连接可选→ 导入SQL脚本。Windows用户可以直接下载mysql-installer-community-8.0.x.msi安装过程中记住你设置的root密码。macOS用户我比较推荐用Homebrewbrew install mysql8.0 brew services start mysql8.0 mysql_secure_installationLinux用户CentOS/Ubuntu直接用包管理器安装比如Ubuntusudo apt update sudo apt install mysql-server-8.0 sudo systemctl status mysql在你执行mysql -uroot -p进入命令行后第一步建议看一下当前的编码和时区SHOW VARIABLES LIKE character_set_server; SHOW VARIABLES LIKE time_zone;如果期间出现Cant connect to local MySQL server through socket /var/run/mysqld/mysqld.sock那是服务没启动别急着改配置文件先systemctl start mysql。很多同学卡在这一步其实只是一个服务未启动的乌龙。3.2 使用Navicat或命令行导入数据库脚本项目里一般会带一个pet_mall.sql文件。用命令行导入是最不容易出错的mysql -uroot -p pet_mall.sql如果SQL文件较大用图形化工具导入反而容易因为网络或内存问题中断。导入完成后验证一下USE pet_mall; SHOW TABLES;看到清晰的表结构后再检查一下用户表里是否有一条测试账号。正常开源项目都会内置一个admin和user账号密码可能是123456也可能是加密后的字符串。你如果发现这个账号无法登录先查一下密码字段里的值是不是密文。3.3 启动SpringBoot后端服务用IDEA打开后端项目一般叫pet-server或backend这类目录。第一次启动前重点看三个文件application.yml数据库连接配置、端口配置pom.xml依赖版本是否完整PetMallApplication.java启动类所在位置这里我必须给个小提示千万不要直接双击jar包运行先用IDEA跑一遍看清日志输出。如果依赖下载失败多半是Maven镜像源问题。在pom.xml的repositories节点或settings.xml里配置阿里云镜像mirror idaliyunmaven/id mirrorOf*/mirrorOf urlhttps://maven.aliyun.com/repository/public/url /mirror当你在控制台看到类似Tomcat started on port(s): 8080的日志时后端就启动了。此时在浏览器访问http://localhost:8080/swagger-ui/index.html如果集成了Swagger或http://localhost:8080/pet/list可以快速验证接口是否通。3.4 启动Vue3前端页面前端项目一般是pet-web或frontend目录。用VS Code打开终端依次执行npm install npm run servenpm install跑完后如果出现ERR! ERESOLVE unable to resolve dependency tree那是Node版本或者依赖冲突问题。我建议使用Node 16或者Node 18这是Vue3生态最友好的两个大版本。可以用nvm管理多版本nvm install 16.20.2 nvm use 16.20.2如果项目基于Vite构建那启动命令可能是npm run dev默认端口大概率是5173。在浏览器看到页面后第一件事就是验证一下能否登录。如果请求报404或跨域十有八九是前端.env配置文件里的VITE_API_BASE_URL没指向后端的http://localhost:8080。3.5 前后端联调与代理配置前后端联调遇到最多的就是跨域问题。开发环境下最简单的方案是在前端根目录创建一个vue.config.jsVue CLI项目或改vite.config.tsVite项目配置代理转发。我用Vite项目举个例子server: { port: 5173, proxy: { /api: { target: http://localhost:8080, changeOrigin: true, rewrite: (path) path.replace(/^\/api/, ) } } }这么配置之后前端请求/api/pet/list会被自动代理到后端/pet/list上。如果你不用代理就得靠后端加CrossOrigin注解或者配置全局CORS过滤器但那毕竟不是前后端分离生产环境的推荐做法。因为生产环境里前后端往往由Nginx统一托管根本不存在跨域问题你在本地开发时学会代理能让代码离生产环境更近一步。4. 常见问题与排查技巧实录这部分是全文的精华因为这些问题是我见过、踩过、帮别人验过的最典型问题。做成一个速查表更好用。现象根因解决方案SpringBoot启动时报Access denied for user rootlocalhost数据库账号密码不对检查application.yml密码对比root是否可以命令行登录前端页面能打开但列表接口404前端请求路径层级不对检查代理配置和axios的baseURL设置修改数据库数据后前端不刷新后端缓存了列表或前端静态缓存重启后端或强制清浏览器缓存访问后端返回Whitelabel Error PageController路径写错或未返回统一Result查看IDEA控制台异常栈优先看Caused by登录接口报Public Key Retrieval is not allowedMySQL8.0的caching_sha2_password插件问题JDBC URL加allowPublicKeyRetrievaltruenpm run serve后页面白屏前端编译出错控制台有红色报错检查main.js中是否导入Element Plus样式上传图片后看不到图上传路径没配置虚拟映射后端配置WebMvcConfigurer映射本地磁盘目录中文字符乱码MySQL表或连接字符串字符集不一致统一使用utf8mb4连接加characterEncodingutf84.1 关于购物车和订单的经典Bug场景很多新手会碰到一个特别尴尬的情况把商品加入购物车后刷新页面购物车内容没了。排查思路很简单先看购物车表里数据是否存在。如果数据库里有但前端列表空那就是当前登录用户的userId对不上如果数据库里压根没插入那就得看后端save方法有没有被拦截器拦掉事务。我也见过比较“隐蔽”的Bug订单创建成功后库存居然没扣减。如果服务上没加Transactional非常容易出现“订单插入成功但库存扣减失败”的脏数据。所以你在学习这个项目时重点关注一下OrderServiceImpl里的createOrder方法是否带了这个注解Transactional(rollbackFor Exception.class) public Order createOrder(OrderVO vo) { // 校验库存 // 生成订单号 // 扣减库存 // 清空购物车 }当你理解了这个注解的作用再往后看分布式事务、异步消息这些内容时才会有扎实的起点。4.2 常用调试命令与排查心得我习惯把排查问题分为“前端不见数据”和“后端报错误”两层。前端不见数据先在浏览器F12打开Network面板找到对应请求看响应状态码。如果返回200但因为数据格式不符合预期再去看后端接口返回的JSON结构是不是被Result包了一层。后端报错我强烈建议学会看IDEA控制台里的完整异常栈而不是只看最上面一行。尤其是Caused by那几行通常才是真正的病根。不管什么框架分这几步确认异常类型2. 确认异常发生在哪个类的哪一行3. 根据代码逻辑倒推前端传入了什么参数。 很多时候你会发现不是代码逻辑错误而是前端传了个null参数或者时间字段传了一个字符串格式后端解析不了。4.3 把项目变成自己的二次开发扩展建议跑通一个源码项目只是第一步把它改造成带个人特色的项目才是课设高分、面试加分的关键。我个人建议你在原项目基础上试着重写两个模块第一个是把用户密码从明文改成BCrypt加密。原项目用什么算法不一定但你要自己会加盐加密这是工作面试一定会问的安全知识点。第二个是给后台增加一个“宠物图片上传”功能把图片存到本地磁盘或MinIO实现真正的文件存储与预览。这远比单纯把图片Base64写进数据库要专业得多。我见过有些同学打算直接在“宠物之家”项目里加一套秒杀功能但我劝你别急先跑通JWT登录认证逻辑才是关键。因为很多项目的登录只是简单比对用户名密码把Session换成JWT令牌、配合前端路由守卫你的项目会瞬间变得值钱很多。4.4 换数据库版本时我总结的通用步骤这年头开发机装MySQL8.0很常见但有一部分公司的服务器还在用MySQL5.7。如果你把项目从8.0切到5.7或者反过来重点检查三项JDBC驱动版本8.0要用com.mysql.cj.jdbc.Driver5.7可以用com.mysql.jdbc.Driver但最好统一用cj表引擎是否都支持两个版本都支持InnoDB没问题SQL语法兼容情况尤其是某些8.0才有的窗口函数、CTE表达式5.7里跑不了。在这个宠物商城项目里常用SQL基本不涉及这些高阶特性所以换库版本的低成本试错正好可以帮你加深对数据库差异的理解。最后再分享一个小技巧在一个完整的SpringBoot Vue3项目里跑通全流程之后我建议你去干一件“脏活”手动把数据库表删掉两张然后仅凭SQL脚本重新建库建表再启动项目。做完这一步你对这个项目的数据表依赖关系就门儿清了。如果碰到清空购物车、用户登录状态丢失这类问题也能第一时间从数据流上定位。很多人在网上下一堆源码真正吃透的却没几个。区别往往就在于你有没有在一开始把它当作一个“产品”去折腾而不是一个“示例”去运行。这个宠物商城代码量不算大模块划分很典型特别适合作为你Java Web路上的一个标记点——跑通它你的前端调试能力、后端接口设计能力和数据库排查能力都会比之前上一个台阶。
返回列表