★ ORM 设计哲学:g.DB 与链式操作、Scan/All 区别

结论:GoFrame ORM(gdb)以“链式操作 + 约定映射”为核心:g.DB() 是单例数据库入口,Model().Where()...Scan() 一气呵成;All 返回原始结果集,Scan 按目标结构体自动映射;配合 dao 代码生成与软删除等约定,日常 CRUD 几乎不写手拼 SQL。

一、核心概念

  • g.DB():默认分组单例(g.DB("order") 取其他分组),配置在 database 节点。
  • 链式起点:g.Model("user") 或生成的 dao.User.Ctx(ctx)。
  • 常用链式:Where/WherePri/Fields/Order/Group/Having/Limit/Page/Scan 等。
  • 取数方法:All()→gdb.Result(原始记录集);One()→单条 gdb.Record;Scan(&obj) 自动映射到结构体/切片/基本类型。
  • 字段安全:条件参数用 ? 占位或 map/struct 传参,杜绝字符串拼接注入。

二、Scan 与 All 对比

方法返回适用
All()gdb.Result,需再手动转换只要原始数据/二次加工
One()gdb.Record 单条取单行原始数据
Scan(&users)自动映射任意目标直接进业务结构体,最常用

代码示例

type User struct {
    Id   int64  `json:"id"`
    Name string `json:"name"`
    Age  int    `json:"age"`
}

// 列表:Scan 到结构体切片
var users []User
err := g.Model("user").Ctx(ctx).
    Where("age > ?", 18).
    OrderAsc("id").
    Limit(10).
    Scan(&users)

// 单条:按主键取
var u User
err := dao.User.Ctx(ctx).WherePri(1).Scan(&u)

// 约定:存在 deleted_at 字段则自动软删除
_, _ = dao.User.Ctx(ctx).WherePri(1).Delete()          // UPDATE deleted_at=now
_ = dao.User.Ctx(ctx).Unscoped().WherePri(1).Scan(&u)  // Unscoped 忽略软删除

常见追问 / 记忆点

  • 追问:created_at/updated_at 谁维护?→ 表存在这些字段时 gdb 自动写入维护,属“约定优于配置”(以官方文档为准)。
  • 追问:与 GORM 的链式有何差异?→ 风格类似,但 gdb 与 gf 的 dao 生成、日志、错误码、软删除约定深度打通。
  • 记忆点:All 拿原始、Scan 进结构体、Unscoped 开软删、Ctx 永远首参。
笔记加载中…