ORM 写操作:Insert/Update/Delete 与批量写入

引言

写操作是数据层另一条主线。gdb 提供 Insert(含批量)、UpdateDelete 等链式方法,返回 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 链式操作章节为准。

笔记加载中…