这个零食商城项目是我去年带学生完成的毕业设计,采用SpringBoot+Vue的前后端分离架构,实现了从商品管理到用户下单的完整电商流程。相比市面上常见的课程设计,我们在这个项目中加入了Redis缓存、Sa-Token权限控制和ECharts数据可视化等企业级应用特性,使得这个毕设既有教学价值又具备一定的商业实用性。
系统分为管理端和用户端两个部分。管理端采用经典的CRUD架构,包含商品管理、订单处理等12个功能模块;用户端则实现了注册登录、商品浏览、购物车、订单管理等标准电商功能。特别值得一提的是,我们通过Redis缓存热门商品数据,使得首页加载速度提升了3倍左右,这个优化方案我会在后面详细讲解。
选择SpringBoot 2.7作为后端框架主要基于三个考虑:
数据库选用MySQL 8.0而非5.7版本,主要是看中了它的:
这里有个实际开发中的经验:在application.yml中建议配置以下MySQL连接参数:
yaml复制spring:
datasource:
hikari:
connection-timeout: 30000
maximum-pool-size: 20
idle-timeout: 600000
max-lifetime: 1800000
Vue 3的组合式API相比Options API更适合电商这类复杂前端应用。我们主要采用以下技术组合:
特别提醒:在大型电商项目中,一定要做好组件拆分。我们的实践是将商品卡片、分类导航等高频组件单独封装,通过props控制行为,例如:
vue复制<template>
<ProductCard
:product="item"
:show-price="true"
@add-to-cart="handleAddCart"
/>
</template>
商品表采用纵向分表设计:
这种设计带来两个好处:
商品搜索我们实现了两种方案:
购物车采用混合存储策略:
关键Redis数据结构:
java复制// 用户购物车 hash结构
// key: cart:{userId}
// field: skuId
// value: 商品数量
redisTemplate.opsForHash().put("cart:"+userId, skuId, quantity);
注意事项:Redis存储购物车时需要设置过期时间(通常7-30天),避免长期占用内存
订单状态机设计:
支付流程我们采用策略模式封装,便于接入不同支付渠道:
java复制public interface PaymentStrategy {
PayResult pay(Order order);
boolean refund(Order order);
}
// 支付宝实现
@Service
public class AlipayStrategy implements PaymentStrategy {...}
// 微信支付实现
@Service
public class WechatPayStrategy implements PaymentStrategy {...}
我们针对三类数据实施缓存:
缓存更新策略采用经典的Cache-Aside模式:
java复制public Product getProduct(Long id) {
// 1. 先查缓存
Product product = redis.get("product:"+id);
if(product == null) {
// 2. 查数据库
product = productMapper.selectById(id);
// 3. 写缓存
redis.setex("product:"+id, 300, product);
}
return product;
}
针对订单表做了以下优化:
查询优化示例:
sql复制-- 不好的写法
SELECT * FROM orders WHERE status = 1 ORDER BY create_time DESC;
-- 优化后
SELECT id,order_no,amount FROM orders
WHERE status = 1 AND create_time > '2023-01-01'
ORDER BY create_time DESC LIMIT 20;
采用Sa-Token实现以下安全机制:
典型配置示例:
java复制@SaCheckLogin
@SaCheckPermission("order:query")
@GetMapping("/orders")
public List<Order> listOrders() {
// ...
}
采用Docker Compose编排服务:
yaml复制version: '3'
services:
app:
image: java:8-jre
ports:
- "8080:8080"
volumes:
- ./app.jar:/app.jar
command: java -jar /app.jar
redis:
image: redis:6
ports:
- "6379:6379"
volumes:
- ./redis-data:/data
Nginx配置要点:
nginx复制server {
listen 80;
server_name mall.example.com;
location / {
root /var/www/mall;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8080;
}
}
在实际开发过程中,我们遇到了几个典型问题及解决方案:
这个项目从技术选型到最终上线历时3个月,最大的收获是让我深刻理解了电商系统的复杂度不仅在于功能实现,更在于如何处理高并发、保证数据一致性。特别是缓存与数据库的双写一致性问题,我们最终采用"先更新数据库再删除缓存"的策略,虽然可能存在极短的脏读时间,但实现简单且对业务影响小。