ORM 写操作:Insert/Update/Delete 与批量写入
引言
写操作是数据层另一条主线。gdb 提供 Insert(含批量)、Update、Delete 等链式方法,返回 sql.Result,可拿自增 ID、影响行数等。
概念
- 数据载体:写入内容用
Data方法传入,支持g.Map、结构体、结构体切片等。 - Insert:
Model("user").Data(...).Insert(),单条或批量均可;返回sql.Result,用LastInsertId()取自增主键。 - Update:
Model("user").Data(...).Where(...).Update(),务必带Where,否则更新整表;Delete同理。执行结果用RowsAffected()取影响行数;错误遵循第 07 章逐层 Wrap。
代码示例
package main
import (
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
)
func main() {
ctx := gctx.New()
// 1. 单条插入
result, err := g.DB().Model("user").Ctx(ctx).
Data(g.Map{
"name": "john",
"age": 20,
"status": 1,
}).
Insert()
if err != nil {
panic(err)
}
id, _ := result.LastInsertId()
fmt.Println("insert id =", id)
// 2. 按条件更新
result, err = g.DB().Model("user").Ctx(ctx).
Data(g.Map{"age": 21}).
Where("id", id).
Update()
if err != nil {
panic(err)
}
affected, _ := result.RowsAffected()
fmt.Println("affected =", affected)
// 3. 按条件删除
result, err = g.DB().Model("user").Ctx(ctx).
Where("id", id).
Delete()
if err != nil {
panic(err)
}
deleted, _ := result.RowsAffected()
fmt.Println("deleted =", deleted)
}
批量写入用结构体切片(字段与表列同名即可绑定),也支持 g.List(元素为 g.Map 的切片)直接传字典列表:
type User struct {
Name string
Age int
}
users := []User{
{Name: "tom", Age: 22},
{Name: "lily", Age: 24},
}
result, err := g.DB().Model("user").Ctx(ctx).
Data(users).
Insert()
if err != nil {
panic(err)
}
n, _ := result.RowsAffected()
fmt.Println("batch inserted:", n)
字典列表形态等价于 g.List{{"name": "a", "age": 18}, {"name": "b", "age": 19}},Data 直接接收即可批量写入。
注意点
Update/Delete忘写Where会作用全表:先在测试库验证,生产建议加安全兜底。Insert对不存在的字段会忽略还是报错取决于数据库与配置,字段名建议与表结构对齐。- 批量插入一次别塞太多行,按业务量分批,避免单条 SQL 过大。
- 写操作与查询一样要走
Ctx(ctx);错误统一用 gerror 包装后上抛。
小结
Data 喂数据 + Where 定范围 + Insert/Update/Delete 执行,就是 gdb 写操作的全部套路;批量写入只需换数据形态。多表一起改需要原子性时,进入下一章:事务。写方法细节以官方文档 goframe.org 的 ORM 链式操作章节为准。