Java商城商品分类中心应采用路径前缀法(如/1/5/12/)存储多级分类,Category实体不嵌套children,由独立CategoryTreeBuilder组装树;提供管理、导航、筛选三类接口并严格过滤无效数据;缓存采用先更新DB再重建的强一致策略。

Java商城系统的商品分类中心,核心在于构建一棵稳定、可扩展、支持多级查询与管理的分类树。关键不是堆砌技术,而是理清数据结构、接口设计和实际业务约束。
分类数据模型要支持递归与路径检索
数据库中不建议用简单父子ID硬关联来存分类,容易导致深度查询性能差、路径获取困难。推荐使用“路径前缀法”或“左右值(Modified Preorder Tree Traversal)”两种主流方案:
-
路径前缀法:每个分类记录完整路径,如
/1/5/12/,对应一级分类ID=1、二级ID=5、三级ID=12;查询某分类下所有子类只需path LIKE '/1/5/%',索引友好,开发简单 -
左右值法:适合读多写少、需频繁获取整棵子树的场景;每个节点存
lft和rgt值,子树范围即为lft = ?;但新增/移动节点需更新大量记录,需加事务保护
实际项目中,中小商城优先选路径前缀法,兼顾清晰性与性能;大型平台若对分类变动极少,可考虑左右值优化查询效率。
Java实体与树形结构组装要解耦层级
不要让 Category 实体自己 hold 子列表(如 List),否则容易引发循环引用、JSON序列化异常、懒加载陷阱等问题。正确做法是:
立即学习“Java免费学习笔记(深入)”;
- Category 实体只保留基础字段:
id、name、parentId、path、level等,不含 children 字段 - 提供独立的
CategoryTreeBuilder工具类,接收扁平分类列表,按parentId+path一次性组装成嵌套树(可用 Map 缓存父节点快速查找) -
前端需要树结构时,调用
buildTree(List方法返回 DTO,不污染领域实体)
分类树接口设计需兼顾管理与展示场景
后端至少提供三类标准接口,避免前端反复拼接逻辑:
- 后台管理接口:支持增删改查、拖拽排序(更新 path 和 level)、批量启用/禁用;返回带完整路径和层级的扁平列表
-
前台导航接口:如
GET /api/categories/nav,返回最多3级的精简树(含图标、是否显示、跳转链接等展示字段),做缓存(Redis + 过期时间) -
商品筛选接口:如
GET /api/categories/leaf,只返回叶子节点(即能挂商品的末级分类),用于商品发布页下拉选择
注意:所有接口返回的分类数据,必须过滤掉 isDeleted = true 或 status != ENABLE 的记录,避免脏数据透出。
缓存与一致性不能只靠 Redis setAll
分类树变更频率低但影响广,缓存策略要稳:
- 导航树缓存用
StringRedisTemplate存 JSON 字符串,key 建议带版本号,如category:nav:v2,升级结构时直接换 key - 禁止在更新分类时仅删缓存——万一删除失败,就永久脏了;应采用「先更新 DB,再重建并 set 缓存」的强一致流程
- 给缓存加 5~10 分钟兜底过期时间,防止极端情况(如服务重启未触发重建)导致长期不可用
基本上就这些。分类中心看着简单,但路径设计、树组装时机、缓存粒度这三点没处理好,后期改起来成本很高。










