1. 项目概述
这个基于Java SpringBoot+Vue3+MyBatis的网上宠物店系统,是一个典型的电商类全栈项目。它采用了目前主流的前后端分离架构,前端使用Vue3框架,后端基于SpringBoot构建,数据持久层采用MyBatis,数据库选用MySQL。这种技术组合在中小型电商系统中非常常见,既能保证开发效率,又能满足性能需求。
我在实际开发过程中发现,宠物电商系统相比普通电商有一些特殊需求:需要管理宠物活体的库存状态(如健康状态、疫苗接种情况),商品分类更加复杂(按宠物种类、用品类型等多维度划分),以及更严格的订单时效性要求。这些特点使得系统设计时需要特别考虑业务模型的扩展性。
2. 技术架构解析
2.1 前端技术选型
Vue3作为前端框架有几个明显优势:
- Composition API让代码组织更灵活,特别是对于复杂的商品展示逻辑
- 更好的TypeScript支持,这对电商系统的类型安全很有帮助
- 更小的打包体积,提升页面加载速度
实际开发中,我使用了这些关键组件:
- Vue Router管理路由
- Pinia替代Vuex做状态管理
- Element Plus作为UI组件库
- Axios处理HTTP请求
提示:Vue3的setup语法糖可以大幅减少样板代码,但在大型项目中建议谨慎使用,以免降低代码可读性。
2.2 后端技术栈
SpringBoot 2.7.x版本提供了良好的稳定性和性能:
- 内嵌Tomcat简化部署
- 自动配置减少样板代码
- Actuator提供监控端点
MyBatis-Plus作为ORM框架的选择理由:
- 强大的条件构造器简化复杂查询
- 代码生成器快速创建基础CRUD
- 分页插件处理商品列表分页
数据库选用MySQL 8.0主要考虑:
- JSON字段支持存储商品规格等半结构化数据
- 窗口函数方便实现销售排行榜等分析功能
- 事务性能满足高并发订单创建需求
3. 核心功能实现
3.1 商品管理系统
宠物店商品分为三大类:
- 活体宠物(需要特殊字段:生日、性别、疫苗记录)
- 宠物食品(需要保质期管理)
- 宠物用品(需要规格参数)
数据库设计示例:
CREATE TABLE `product` ( `id` bigint NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL, `category_id` int NOT NULL COMMENT '1-活体 2-食品 3-用品', `price` decimal(10,2) NOT NULL, `stock` int NOT NULL DEFAULT '0', `status` tinyint NOT NULL DEFAULT '1' COMMENT '0-下架 1-上架', `specs` json DEFAULT NULL COMMENT '商品规格', `main_image` varchar(255) DEFAULT NULL, `detail` text, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;3.2 购物车与订单系统
购物车设计考虑点:
- 未登录用户使用浏览器本地存储
- 已登录用户同步到服务端
- 需要实时检查库存
订单状态机实现:
public enum OrderStatus { UNPAID(1, "待支付"), PAID(2, "已支付"), SHIPPED(3, "已发货"), COMPLETED(4, "已完成"), CANCELLED(5, "已取消"), REFUNDED(6, "已退款"); // 省略状态转换校验逻辑 }3.3 支付与物流集成
支付对接方案:
- 沙箱环境测试支付宝/微信支付
- 使用Spring事件机制处理支付回调
- 分布式事务处理订单状态更新
物流信息查询:
- 对接快递鸟API
- 定时任务更新物流状态
- 本地缓存减少API调用
4. 前后端交互设计
4.1 API规范
采用RESTful风格设计:
- GET /api/products - 商品列表
- POST /api/cart/items - 添加购物车
- PUT /api/orders/{id}/cancel - 取消订单
响应统一格式:
{ "code": 200, "message": "success", "data": {...}, "timestamp": 1672531200000 }4.2 安全控制
关键安全措施:
- JWT认证
- 接口权限控制
- XSS过滤
- CSRF防护
- 敏感数据加密
Spring Security配置示例:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/api/auth/**").permitAll() .antMatchers("/api/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .addFilter(new JwtAuthenticationFilter(authenticationManager())) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); } }5. 性能优化实践
5.1 数据库优化
索引策略:
- 商品表:category_id + status 联合索引
- 订单表:user_id + create_time 索引
- 避免过度索引导致写入性能下降
查询优化技巧:
- 分批获取商品详情
- 使用覆盖索引减少回表
- 避免SELECT *
5.2 缓存应用
多级缓存方案:
- 本地Caffeine缓存热点商品
- Redis集群缓存购物车和用户会话
- CDN缓存静态资源
缓存击穿解决方案:
public Product getProductById(Long id) { // 1. 先查缓存 Product product = cache.get(id); if (product == null) { // 2. 获取分布式锁 if (lock.tryLock()) { try { // 3. 再次检查缓存(双重检查) product = cache.get(id); if (product == null) { // 4. 查数据库 product = db.query(id); if (product != null) { // 5. 写入缓存 cache.set(id, product); } } } finally { lock.unlock(); } } } return product; }6. 部署与监控
6.1 容器化部署
Docker编排方案:
version: '3' services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: petstore123 volumes: - mysql_data:/var/lib/mysql redis: image: redis:6 ports: - "6379:6379" backend: build: ./backend ports: - "8080:8080" depends_on: - mysql - redis frontend: build: ./frontend ports: - "80:80"6.2 监控方案
Prometheus + Grafana监控指标:
- JVM内存使用
- 接口响应时间
- 数据库连接池状态
- 缓存命中率
日志收集:
- ELK收集分析日志
- 关键业务操作日志单独存储
- 日志脱敏处理
7. 开发中的经验教训
宠物状态管理:活体宠物需要定期更新状态(如健康检查),最初设计时没有考虑状态历史记录,后来增加了状态变更日志表。
商品规格问题:不同品类商品规格差异很大,最终采用JSON字段+前端动态表单的方案,比固定字段更灵活。
订单超时处理:宠物食品有保质期,订单长时间未支付需要自动释放库存,使用Redis的keyspace notifications实现。
图片存储:最初使用本地存储,迁移到OSS时遇到路径问题,建议从一开始就使用对象存储服务。
测试数据生成:使用Mockaroo生成真实的宠物名称和商品描述,比随机字符串更有助于测试。
这个项目最让我有成就感的是解决了宠物活体库存的并发控制问题。通过Redis分布式锁+数据库乐观锁的双重机制,确保了在高并发下单时不会出现超卖情况。具体实现时需要注意锁的粒度控制和超时设置,避免死锁和长时间阻塞。