ARTICLE DETAIL

建站实战干货

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

基于Spring Boot的宠物商城系统设计与实现

2026/9/13 12:20:07 拓冰建站 浏览量
基于Spring Boot的宠物商城系统设计与实现 简介基于SpringBoot的宠物商城网站源码包面向计算机、电子信息工程等专业的毕业生与课程设计学习者可无缝用于JavaWeb方向的高分毕业设计项目、课程设计或期末大作业。压缩包约20.83MB内部是完整的SpringBootMaven工程结构按后端控制器、业务服务层、MyBatis持久层与实体类分层组织同时包含Vue相关的前端页面、静态资源以及Maven和application配置文件导入IDEA、Eclipse或MyEclipse配置JDK1.8、MySQL5.7和Tomcat8.0/9.0即可运行。代码经过严格测试覆盖宠物分类展示、商品浏览、购物车、订单管理、后台维护等典型商城模块适合分模块阅读学习也能直接二次开发用于毕设答辩或课程展示。从数据库表设计到前端接口调用都有清晰脉络能帮助理解SpringBoot与MyBatis在实际项目中的配合方式同时可作为后续扩展的基础模板。已有299人学习下载遇到环境配置或联调问题可随时与博主交流。1. 宠物商城从零到一为什么Spring Boot是毕业设计的最优解做宠物商城这类B/S架构项目最大的痛点不是功能写不出来而是环境搭到一半就想放弃。JDK装完配MavenMaven配完连MySQL连完MySQL还要处理编码乱码等把Tomcat跑起来时间已经过去一周。这个基于Spring Boot的宠物商城代码把上面这些环节全部压缩成一个可以直接跑起来的工程适合计算机、电子信息工程等专业做毕业设计或课程设计也适合想系统看一遍Java Web全链路的前端同学当后端范本。Spring Boot在这个项目里的价值不只是免去了大量XML配置而是让MyBatis、Ajax、Vue这些技术栈有了清晰的边界。Controller层管参数接收Service层管业务规则Mapper接口管SQL前端页面通过Ajax异步拿JSON数据渲染每一条链路都可以单独调试。接下来直接按「环境初始化 → 核心模块拆解 → 数据层设计 → 部署排错」的顺序把代码里真正关键的部分过一遍。2. 环境选型与工程初始化先把技术栈边界划清楚2.1 为什么是JDK 1.8 Maven 3.6 MySQL 5.7这套代码锁定了JDK 1.8、Maven 3.6、MySQL 5.7不是随便选的。JDK 1.8是Spring Boot 2.x系列最稳定的运行基座lambda表达式和Stream API正好支撑Service层的集合操作Maven 3.6对私服镜像的兼容性比新版本更稳切换阿里云镜像后依赖下载速度提升明显MySQL 5.7的InnoDB引擎在默认事务隔离级别REPEATABLE READ下配合Spring的声明式事务可以避免大部分幻读问题这对订单模块很重要。环境变量的配置是新手最常卡住的地方。JDK装完后JAVA_HOME指向JDK根目录Path里追加%JAVA_HOME%\binMaven同样需要配MAVEN_HOME和Path。验证方式很简单在命令行执行java -version和mvn -v两个命令都能输出版本号就说明环境变量配置没问题。这个环节用IDEA开发时经常被忽略因为IDEA内置了JDK和Maven但一旦脱离IDE执行打包命令环境变量就变成第一个拦路虎。2.2 从pom.xml看依赖边界打开pom.xml核心依赖就六个。spring-boot-starter-web内置Tomcat和Spring MVC是B/S架构的基石mybatis-spring-boot-starter把MyBatis和Spring Boot的自动配置机制连接起来省掉了SqlSessionFactory的手动创建mysql-connector-java负责JDBC底层的网络通信协议lombok用来消减实体类的getter/setter样板代码。parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.3.4.RELEASE/version /parent dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version2.1.4/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version5.1.49/version /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies依赖版本是配合好的直接使用不需要改动。spring-boot-starter-parent作为统一父工程管理了大部分依赖的版本号所以web包不写version也不会报错。mybatis-spring-boot-starter的2.1.4版本适配Spring Boot 2.3.x这个对应关系错了会出现Mapper接口无法注入的启动异常。2.3 配置文件与数据库初始化在application.yml中需要重点关注三块配置数据源链接、MyBatis的XML映射路径、端口号。数据库连接串里characterEncodingutf8必须加上否则中文商户名和宠物名写入MySQL后会出现乱码serverTimezoneAsia/Shanghai解决JDBC驱动与时区不一致导致的报错问题。server: port: 8080 spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/pet_shop?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 123456 mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.petshop.entity configuration: map-underscore-to-camel-case: truemapper-locations指向resources/mapper/下的XML文件这是MyBatis把Java接口和SQL语句关联起来的关键配置。map-underscore-to-camel-case开启后数据库字段create_time可以自动映射到实体类的createTime避免手写ResultMap的繁琐。数据库初始化使用SQLyog或Navicat直接执行项目附带的pet_shop.sql脚本即可但要注意MySQL 5.7的默认字符集。建表语句中DEFAULT CHARSETutf8mb4比utf8多支持emoji字符宠物商品名称里偶尔会带特殊符号建议统一使用utf8mb4。3. 宠物商品模块与检索MyBatis动态SQL加Ajax异步交互3.1 商品表的字段设计与状态位宠物商城的核心表是宠物商品表设计上有一个容易被忽略的点用status状态位控制上下架而不是物理删除数据。这样用户在浏览商品时通过WHERE status 1过滤管理员下架时只更新状态位。即使以后要恢复上架或者做操作日志回溯数据都还完整在表里。字段名类型说明idint(11)主键自增pet_namevarchar(50)宠物名称categoryvarchar(20)分类如猫、狗、鸟pricedecimal(10,2)价格用decimal避免浮点误差stockint(11)库存数量imagevarchar(255)商品图片路径statustinyint(4)1上架0下架create_timedatetime创建时间price字段用decimal(10,2)而不是double这是涉及金额场景的硬性要求。double在MySQL里是近似值计算0.1加0.2可能得到0.30000000000000004而decimal是精确类型Java侧的BigDecimal与之一一对应订单金额计算时不会出现分位误差。3.2 动态SQL实现多条件检索商品列表页通常会提供分类筛选和关键字搜索两个入口如果用固定SQL写死查询条件每增加一个筛选维度就要新增一个Mapper方法。MyBatis的where和if标签能动态拼接SQL片段一个方法覆盖所有查询组合。select idsearchPets parameterTypemap resultTypecom.petshop.entity.Pet SELECT id, pet_name, category, price, stock, image, status FROM pet where if testcategory ! null and category ! AND category #{category} /if if testkeyword ! null and keyword ! AND pet_name LIKE CONCAT(%, #{keyword}, %) /if AND status 1 /where ORDER BY create_time DESC /select这段SQL的逻辑在于分类过滤使用精准匹配关键字搜索使用LIKE模糊匹配两个条件互相独立。Mapper接口对应的Java方法签名是ListPet searchPets(Param(category) String category, Param(keyword) String keyword)参数用Param注解命名和XML里的#{category}、#{keyword}一一对应。如果某个参数传了空值if标签判断为false对应的条件就不会拼进SQL。3.3 Controller层到Ajax的数据链路宠物商城的Controller层返回的是JSON不是页面前后端的交互通过Ajax完成。前端Vue实例在mounted阶段发起请求后端接口收到参数后走Service层查询数据库最后以JSON格式把商品数据返回给浏览器渲染。RestController RequestMapping(/pet) public class PetController { Autowired private PetService petService; RequestMapping(/search) public Result search(RequestParam(required false) String category, RequestParam(required false) String keyword) { ListPet petList petService.searchPets(category, keyword); return Result.success(petList); } }RestController表示该类的所有方法返回值自动序列化为JSON不需要在方法上加ResponseBody。RequestParam(required false)声明两个参数都是可选的前端不传时值为null正好匹配动态SQL的空值判断。Service层在Controller和Mapper之间做了一层缓冲虽然当前代码可能只是直接透传但保留这层设计的意义在于如果以后需要加缓存、加权限校验、做数据权限过滤都可以在Service层统一处理不必改动Controller和Mapper的代码。前端Vue部分使用axios.get(/pet/search, {params: params})发送请求params对象里的category和keyword会根据用户的操作动态组装。4. 购物车到订单事务边界与订单状态流转4.1 购物车与订单的表关系宠物商城的购物车表和订单表是两套独立的数据结构。购物车是用户未确认的意向商品集合可以随时增删改订单是已经确认并进入生命周期管理的正式数据。把购物车和订单分开设计才能支持「用户把商品加入购物车几天后再下单」的真实场景。订单表的字段需要覆盖完整的交易链路信息订单号、用户ID、总金额、状态、收货地址、创建时间。订单明细表则记录订单里每一件宠物的快照信息——宠物名称、单价、数量、小计。快照的意思是即使后续商品改价或者下架订单历史里的价格和名称保持下单时的数据不变。4.2 事务控制下的库存扣减下单的核心动作是「扣减库存 创建订单 创建订单明细」这三个动作必须同时成功或者同时失败。如果在创建订单成功后扣库存失败用户看到的是订单已生成但实际库存没减后面发货时才发现库存不够这就是典型的数据不一致。Transactional(rollbackFor Exception.class) public Order createOrder(Integer userId, Integer petId, Integer quantity) { // 1. 检查库存是否充足 Pet pet petMapper.selectByIdForUpdate(petId); if (pet.getStock() quantity) { throw new RuntimeException(库存不足); } // 2. 扣减库存 petMapper.reduceStock(petId, quantity); // 3. 创建订单 Order order new Order(); order.setUserId(userId); order.setTotalPrice(pet.getPrice().multiply(BigDecimal.valueOf(quantity))); order.setStatus(0); orderMapper.insert(order); // 4. 写入订单明细 OrderItem item new OrderItem(); item.setOrderId(order.getId()); item.setPetId(petId); item.setPetName(pet.getPetName()); item.setPrice(pet.getPrice()); item.setQuantity(quantity); orderItemMapper.insert(item); return order; }Transactional(rollbackFor Exception.class)声明了事务边界方法内任何一个环节抛出异常前面的数据库操作全部回滚。rollbackFor Exception.class要特意写出来因为Spring默认只对RuntimeException回滚检查异常不会触发回滚。selectByIdForUpdate使用悲观锁在查询时对该行数据加排他锁锁住之后到事务结束前其他事务不能再修改这条库存记录从机制上避免超卖。4.3 订单状态机的核心节点订单状态建议用整数表示而不是直接用字符串存储状态名称。整数的好处是占空间小、查询快、扩展方便在代码里用常量或者枚举做映射。宠物商城的订单状态流转相对简单核心节点是待付款、已付款、已发货、已完成外加一个取消状态。状态值含义可触发操作0待付款去支付 / 取消订单1已付款发货仅管理员2已发货确认收货3已完成无4已取消无状态流转的校验逻辑放在Service层统一管理不能在前端自由跳转。比如订单从待付款直接改成已发货是不允许的必须有支付记录做支撑。更新时间字段update_time记录状态变更的时间点配合操作日志表可以还原整个订单的时间轴。5. 打包部署与排错从IDEA到可直接演示的完整流程5.1 一键打包与多环境运行在IDEA的Terminal窗口里执行mvn clean package -DskipTestsMaven会先清理target目录然后执行编译、资源复制、打包全流程。-DskipTests跳过测试代码的编译和执行能明显缩短打包时间。打包完成后target目录下会生成pet-shop-0.0.1-SNAPSHOT.jar这个jar包就是Spring Boot内嵌Tomcat的可执行文件。# 默认使用application.yml的配置启动 java -jar target/pet-shop-0.0.1-SNAPSHOT.jar # 指定外部配置文件启动 java -jar target/pet-shop-0.0.1-SNAPSHOT.jar --spring.config.location/opt/config/application.yml # 指定端口启动 java -jar target/pet-shop-0.0.1-SNAPSHOT.jar --server.port9090日常开发在IDEA里直接运行启动类即可但毕业设计答辩现场通常需要独立演示环境。这里建议打包前把项目里的application.yml复制一份到jar包同级的config目录因为Spring Boot的配置加载优先级是外部config目录 外部根目录 classpath内部外部配置可以临时修改数据库地址或端口不用重新打包。5.2 三个高频异常排查顺序启动时遇到java.sql.SQLException: Unknown database先确认MySQL里是否执行了初始化SQL脚本再检查database名称和连接串里的pet_shop是否完全一致包括大小写。MySQL在Linux环境下对数据库名区分大小写Windows下不区分这个差异在跨平台部署时最容易踩坑。遇到Invalid bound statement (not found)表示Mapper接口和XML文件没有正确绑定。排查顺序是先确认application.yml里的mapper-locations路径和实际目录结构一致再检查XML文件里的namespace是否和Mapper接口的全限定名完全一致。很多IDEA在复制包名时会把路径写错导致namespace对不上。# 常见目录结构 ├── main │ ├── java │ │ └── com/petshop/mapper/PetMapper.java │ └── resources │ └── mapper/PetMapper.xml字段名映射不上时优先看map-underscore-to-camel-case配置是否开启。比如数据库字段pet_name默认映射到实体的petName如果开启了驼峰转换仍然拿不到值检查实体属性是否写了Data注解Lombok没有生效时实体类缺少getter/setter方法MyBatis会反射失败。5.3 用日志和接口工具验证模块完整性部署完成后不要急着点页面用Postman或浏览器开发者工具直接请求几个核心接口能更快定位问题层级。先请求/pet/search不带任何参数如果返回了商品列表说明数据库连接、Mapper映射、Controller链路都通收到404则看Controller类的RequestMapping路径是否拼写完整。# 查看Tomcat线程池与内存情况 jps -l jinfo -flags pid启动时发现内存溢出类报错在启动命令中追加-Xms256m -Xmx512m限制JVM堆内存。调整完参数后查看端口占用情况netstat -ano | grep 8080确认没有其他进程抢占端口最后用浏览器访问系统首页走一遍「商品列表 → 详情 → 加入购物车 → 下单」的完整流程收尾。本文还有配套的精品资源点击获取