商品模型需带GORM标签和binding校验规则,ID须gorm:"primaryKey",Stock用int64,字符串字段加size限制;CRUD路由须显式绑定JSON、检查err、区分读写库、用游标分页替代OFFSET。

商品模型定义要带GORM标签和校验规则
不加 GORM 标签会导致数据库字段映射失败,不加 binding 会导致前端传空值时后端无法拦截。比如 Price 字段必须标记 binding:"required",否则用户提交价格为 0 的商品也能过校验。
常见错误现象:POST 商品接口返回 200 但数据库没插入数据,大概率是结构体字段没加 gorm:"column:name" 或类型不匹配(如用 int 接收 JSON 中的浮点数)。
-
ID字段必须带gorm:"primaryKey",否则 GORM 不会自增 -
Stock建议用int64而非int,避免在高并发扣减时溢出 - 字符串字段如
Name、Description要加size限制,防止超长写入触发 MySQL 严格模式报错
CRUD路由注册别漏掉中间件和参数绑定
直接用 router.POST("/product", handler.Create) 是不够的。Gin 默认不自动解析 JSON body,必须显式调用 c.ShouldBindJSON(&product),否则 product 始终是零值。
容易踩的坑:在 Create 处理函数里忘记检查 err,导致校验失败也返回 200;或在 Update 时用 db.Save() 而非 db.Where("id = ?", id).Updates(),造成未传字段被覆盖为零值。
- 所有写操作路由建议加
auth.Middleware(),哪怕只是简单 token 验证 -
GET /products分页参数必须用c.Query("page")和c.Query("page_size")获取,不能硬编码默认值 - 删除接口要用
DELETE /products/:id路由,别写成POST /products/delete?id=123,违反 REST 规范且难做权限控制
GORM查询要区分读写库,尤其在主从架构下
商品列表接口走从库,商品上架/下架操作必须走主库。如果全用同一个 *gorm.DB 实例,读写分离就形同虚设。
性能影响明显:某次压测发现,商品列表接口 P95 延迟从 120ms 涨到 850ms,查因是所有查询都打到了主库,CPU 直接跑满。
- 推荐在
handlers/product.go里注入两个 DB 实例:readDB和writeDB -
List函数只用readDB.Find(&products),UpdateStatus必须用writeDB.Model(&Product{}).Where("id = ?", id).Update("status", status) - 注意 GORM 的
First()默认不走预加载,查商品+分类需显式写Preload("Category")
分页必须用游标方式替代 OFFSET
当商品表超过 10 万行,LIMIT 20 OFFSET 10000 查询会变慢到 2s+,而游标分页能稳定在 20ms 内。
真实场景中,运营后台翻到第 500 页时,OFFSET 已达 10000,MySQL 要扫描并丢弃前 10000 行——这和业务无关,纯属数据库负担。
- 游标字段必须是带索引的单调字段,如
created_at或id,不能用name - 前端传参改为
cursor(上一页最后一条的id)和direction=next/prev,后端生成 WHERE 条件:WHERE id > ? ORDER BY id ASC LIMIT 20 - 首次请求无 cursor,用
WHERE id > 0起始,避免漏掉 id=1 的商品


















