1. 项目概述:原色蛋糕商城的设计初衷与技术选型
去年帮学弟调试毕业设计时,发现市面上80%的JavaWeb电商项目还在用十年前的技术栈。这个基于SpringBoot的蛋糕商城项目,正是为了打破这种僵化模式而设计的典型教学案例。作为完整的商业级项目,它涵盖了从需求分析到部署上线的全流程,特别适合计算机专业学生作为毕业设计参考。
项目采用经典的B/S架构,前端使用Thymeleaf模板引擎替代传统的JSP,后端基于SpringBoot 2.7整合MyBatis-Plus,数据库选用MySQL 8.0。这种技术组合既保留了JavaWeb的核心技术要点,又引入了现代开发框架的便利性。我在实际开发中发现,相比纯Servlet方案,SpringBoot的自动配置特性能让开发者更专注于业务逻辑实现。
关键提示:选择SpringBoot而非传统SSM框架,主要考虑到毕业生往往在有限时间内需要快速搭建可演示的系统。SpringBoot内嵌Tomcat的特性,使得项目打包后可直接通过java -jar命令运行,极大简化了部署流程。
2. 核心功能模块拆解与实现
2.1 用户系统设计要点
用户模块采用RBAC(基于角色的访问控制)模型,区分普通用户、会员和管理员三种角色。这里有个容易被忽视的细节:密码存储必须使用BCrypt加密而非MD5。我在用户表中设计了如下关键字段:
CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '登录账号', `password` varchar(100) NOT NULL COMMENT 'BCrypt加密密码', `salt` varchar(20) DEFAULT NULL COMMENT '加密盐值', `role` enum('user','member','admin') DEFAULT 'user', `phone` varchar(20) DEFAULT NULL COMMENT '手机号(登录账号)', `avatar` varchar(255) DEFAULT NULL COMMENT '头像URL', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `idx_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;实现登录功能时,特别注意要加入验证码防护。采用Kaptcha组件生成图形验证码,配合Redis设置60秒过期时间:
@GetMapping("/captcha") public void captcha(HttpServletRequest request, HttpServletResponse response) { // 生成验证码文本 String text = producer.createText(); // 存入Redis,key为sessionId redisTemplate.opsForValue().set( "captcha:" + request.getSession().getId(), text, 60, TimeUnit.SECONDS); // 输出图片流 BufferedImage image = producer.createImage(text); response.setContentType("image/jpeg"); ImageIO.write(image, "jpg", response.getOutputStream()); }2.2 商品管理与展示策略
蛋糕商品系统采用分类+标签的双维度管理。核心表关系如下:
- 商品表(product):存储基础信息
- 商品分类表(category):树形结构分类
- 商品标签表(tag):打标管理
- 商品SKU表(sku):规格价格库存
前端展示时特别注意图片懒加载优化。使用Thymeleaf的片段渲染功能实现商品卡片组件:
<div th:fragment="productCard(product)" class="col-md-4 mb-4"> <div class="card h-100"> <img th:src="${product.coverUrl}" class="card-img-top lazy" alt="..." loading="lazy"> <div class="card-body"> <h5 class="card-title" th:text="${product.name}"></h5> <p class="card-text" th:text="${product.description}"></p> <div class="d-flex justify-content-between"> <span class="text-danger" th:text="'¥'+${#numbers.formatDecimal(product.minPrice,1,2)}"></span> <a th:href="@{/product/}+${product.id}" class="btn btn-sm btn-outline-primary">查看详情</a> </div> </div> </div> </div>2.3 购物车与订单系统实现
购物车设计采用混合存储方案:已登录用户数据存MySQL,未登录用户存浏览器LocalStorage。关键数据结构:
public class CartItem { private Long skuId; // 商品SKU ID private Integer count; // 购买数量 private Boolean checked; // 是否选中 } // 订单主表 public class Order { private String orderNo; // 订单编号(时间戳+随机数) private Long userId; // 用户ID private BigDecimal payment; // 实付金额 private Integer status; // 订单状态 private List<OrderItem> items; // 订单明细 }订单编号生成采用Snowflake算法避免重复:
public class OrderNoGenerator { private static final Snowflake snowflake = new Snowflake(1, 1); public static String generate() { return "ORD" + snowflake.nextId(); } }3. 典型技术难点解决方案
3.1 高并发下的库存扣减
使用MySQL乐观锁+Redis预减库存方案。关键步骤:
- 商品详情页加载时,从Redis获取实时库存显示
- 提交订单时先执行Redis原子减操作
- 创建订单成功后异步同步库存到MySQL
public boolean reduceStock(Long skuId, Integer num) { String key = "stock:" + skuId; // Lua脚本保证原子性 String script = "if tonumber(redis.call('get', KEYS[1])) >= tonumber(ARGV[1]) then " + "return redis.call('decrby', KEYS[1], ARGV[1]) " + "else return -1 end"; Long result = redisTemplate.execute( new DefaultRedisScript<>(script, Long.class), Collections.singletonList(key), String.valueOf(num)); return result != null && result >= 0; }3.2 支付状态异步通知处理
采用支付宝沙箱环境模拟支付流程时,需要注意签名验证和幂等处理:
@PostMapping("/pay/notify") public String payNotify(HttpServletRequest request) { // 验证签名 if(!AlipaySignature.rsaCheckV1(/*参数*/)) { return "failure"; } String orderNo = request.getParameter("out_trade_no"); // 幂等检查 Order order = orderService.getByNo(orderNo); if(order.getStatus() != OrderStatus.UNPAID) { return "success"; } // 更新订单状态 orderService.updateStatus(orderNo, OrderStatus.PAID); return "success"; }4. 项目部署与性能优化
4.1 多环境配置管理
使用SpringBoot的Profile机制管理开发、测试、生产环境配置:
# application-dev.yml server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/cake_dev username: dev password: dev123 # application-prod.yml spring: datasource: url: jdbc:mysql://prod-db:3306/cake_prod?useSSL=false&serverTimezone=Asia/Shanghai username: prod_user password: ${DB_PASSWORD} redis: host: redis-master4.2 Docker化部署方案
编写Dockerfile实现一键部署:
FROM openjdk:11-jre WORKDIR /app COPY target/cake-shop.jar ./app.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","app.jar","--spring.profiles.active=prod"]使用docker-compose编排MySQL和Redis:
version: '3' services: app: build: . ports: - "8080:8080" depends_on: - redis - mysql redis: image: redis:6-alpine ports: - "6379:6379" mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: cake_prod ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql volumes: mysql_data:5. 毕业设计答辩要点
5.1 系统演示技巧
准备三条典型用户路径:
- 游客浏览→注册登录→添加购物车→下单支付
- 管理员登录→商品上架→订单管理
- 会员登录→优惠券领取→生日特权使用
实测建议:在本地hosts文件配置域名(如www.cake.test),比用IP:Port演示更专业。提前录制备用视频以防现场网络问题。
5.2 技术问答准备
常见问题及回答方向:
- 为什么选择SpringBoot而不是SSM? → 简化配置、内嵌容器、starter自动装配优势
- 如何防止重复下单? → 前端防重复提交+后端订单号唯一索引
- 数据库设计遵循哪些范式? → 说明主要表满足第三范式(3NF)的情况
5.3 文档编写规范
论文目录建议结构:
1. 绪论(背景意义) 2. 关键技术分析(SpringBoot/MySQL等) 3. 系统分析(用例图、流程图) 4. 系统设计(ER图、类图) 5. 系统实现(核心代码截图) 6. 系统测试(用例表、压力测试) 7. 总结与展望特别提醒:所有截图需保持风格统一,建议使用Snipaste等工具添加说明性标注。数据库设计部分至少包含5张主要表的详细字段说明。