markdown复制## 1. 项目概述与核心价值
这个日用品销售系统项目是典型的电商类课程设计/毕业设计选题,采用SpringBoot+MyBatis主流技术栈实现。我在实际开发中发现,这类系统虽然业务逻辑相对简单,但完整涵盖了用户管理、商品展示、购物车、订单处理、支付对接等电商核心模块,特别适合用来练手SpringBoot全栈开发。系统采用经典的三层架构(Controller-Service-Dao),前端用Thymeleaf模板引擎渲染,数据库选用MySQL 8.0,源码包还附带了完整的项目文档和SQL脚本。
> 提示:选择日用品作为商品类目有个隐藏优势——不需要处理复杂的SKU属性(比如服装的尺码/颜色),更适合初学者快速实现核心功能。
## 2. 技术选型与架构设计
### 2.1 为什么选择SpringBoot
SpringBoot的自动配置特性让项目搭建变得极其简单。我实测从零开始到跑通第一个接口只需:
1. 用Spring Initializr生成基础项目(勾选Web/MyBatis/MySQL依赖)
2. 配置application.yml数据库连接
3. 编写@RestController测试接口
整个过程不超过15分钟,这对课程设计这种有时间限制的项目非常友好。
### 2.2 数据库设计要点
商品表的设计值得特别注意:
```sql
CREATE TABLE `product` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '商品名称',
`category_id` int DEFAULT NULL COMMENT '分类ID',
`price` decimal(10,2) NOT NULL COMMENT '售价',
`stock` int NOT NULL DEFAULT '0' COMMENT '库存',
`image_url` varchar(255) DEFAULT NULL COMMENT '主图URL',
`detail` text COMMENT '商品详情',
`status` tinyint DEFAULT '1' COMMENT '状态:1-上架 0-下架',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
关键设计考量:
- 价格使用DECIMAL(10,2)避免浮点精度问题
- 库存字段设计为有符号整数(允许超卖时为负值)
- 图片存储URL而非BLOB,符合实际生产规范
3. 核心功能实现细节
3.1 购物车模块的并发控制
购物车的"增减数量"操作需要特别注意并发问题。我的实现方案:
java复制@Transactional
public void updateCartItem(Integer userId, Integer productId, Integer quantity) {
// 先检查库存
Product product = productMapper.selectById(productId);
if(product.getStock() < quantity) {
throw new RuntimeException("库存不足");
}
// 乐观锁更新
int rows = cartMapper.updateQuantity(userId, productId, quantity);
if(rows == 0) {
throw new ConcurrentModificationException("购物车数据已被修改");
}
}
踩坑记录:最初没加@Transactional注解,在高并发测试时出现了库存扣减不一致的情况。
3.2 订单状态的幂等设计
订单支付回调接口必须实现幂等性处理:
java复制public String payCallback(String orderNo, String payNo) {
Order order = orderMapper.selectByOrderNo(orderNo);
// 状态机校验
if(order.getStatus() != OrderStatus.UNPAID) {
return "SUCCESS"; // 已处理过的请求直接返回成功
}
// 更新订单状态(带版本号校验)
int rows = orderMapper.updateStatus(
orderNo,
OrderStatus.PAID,
payNo,
order.getVersion()
);
if(rows == 0) {
log.warn("订单并发更新冲突:{}", orderNo);
}
return "SUCCESS";
}
4. 典型问题排查实录
4.1 商品搜索性能优化
当商品数量超过1万条时,模糊查询出现明显延迟:
code复制SELECT * FROM product WHERE name LIKE '%牙膏%'
优化方案:
- 添加全文索引
sql复制ALTER TABLE product ADD FULLTEXT INDEX ft_idx_name(name);
- 改用MATCH语法
sql复制SELECT * FROM product
WHERE MATCH(name) AGAINST('牙膏' IN NATURAL LANGUAGE MODE)
实测查询时间从1200ms降至80ms。
4.2 订单导出OOM问题
导出大量订单数据时出现内存溢出,解决方案:
java复制// 旧方案(全量加载到内存)
List<Order> orders = orderMapper.selectAll();
// 新方案(流式处理)
try(MyBatisCursor<Order> cursor = orderMapper.selectAllByCursor()) {
while(cursor.hasNext()) {
Order order = cursor.next();
// 处理单条数据
}
}
配合MyBatis的ResultHandler可以实现真正的流式导出。
5. 项目扩展建议
5.1 加入Redis缓存
商品详情这类读多写少的数据非常适合缓存:
java复制public Product getProductById(Integer id) {
String cacheKey = "product:" + id;
Product product = redisTemplate.opsForValue().get(cacheKey);
if(product == null) {
product = productMapper.selectById(id);
redisTemplate.opsForValue().set(
cacheKey,
product,
30, TimeUnit.MINUTES
);
}
return product;
}
记得在商品更新时删除对应缓存。
5.2 接口安全加固
生产环境必须增加:
- JWT token认证
- 敏感参数加密(如金额、用户ID)
- 防XSS过滤(商品详情字段)
- 接口限流(Guava RateLimiter)
6. 开发环境搭建指南
6.1 快速启动步骤
- 导入SQL脚本(项目根目录/sql/init.sql)
- 修改application.yml中的数据库配置
- 启动主类:
com.example.MallApplication - 访问 http://localhost:8080
6.2 关键配置项说明
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/mall?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
thymeleaf:
cache: false # 开发时关闭模板缓存
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true # 自动驼峰转换
7. 文档编写技巧
毕业设计文档最容易丢分的三个地方:
- 时序图要规范(使用PlantUML绘制)
- 测试用例要覆盖边界条件(如空购物车结算)
- 性能指标要量化(用JMeter压测报告)
建议文档结构:
code复制1. 引言(项目背景+意义)
2. 需求分析(用例图+流程图)
3. 系统设计(ER图+类图)
4. 核心实现(关键代码+截图)
5. 系统测试(用例表+压力测试)
6. 总结(创新点+不足)
我在实际开发中最耗时的其实是文档的"系统测试"章节,建议提前设计好测试用例模板,边开发边记录测试结果,避免最后补文档时遗漏测试场景。
code复制