gorm model何时用

一、什么时候要用 Model

必须使用 Model 的场景

  1. 更新操作时
1
2
3
4
5
// ✅ 必须用 Model 指定要更新的表
DB.Model(&User{}).Where("name = ?", "张三").Update("age", 26)

// ❌ 错误:不知道要更新哪个表
DB.Where("name = ?", "张三").Update("age", 26)
  1. 只想指定表名,不需要查询结果时
1
2
3
4
5
6
// 只指定表,进行聚合查询
var count int64
DB.Model(&User{}).Where("age > ?", 18).Count(&count)

// 联合查询时指定主表
DB.Model(&User{}).Joins("Profile").Find(&users)
  1. 使用 Updates 更新多个字段时
1
2
// ✅ 明确指定要更新的表
DB.Model(&User{}).Where("id = ?", 1).Updates(User{Name: "new", Age: 20})

不需要 Model 的场景

  1. 查询并填充结果时(通过结果推断表名)
1
2
3
4
5
6
7
var user User
// ✅ Find/First/Last 通过 user 知道是 User 表
DB.First(&user) // 通过 &user 推断
DB.Where("name = ?", "张三").First(&user)

var users []User
DB.Find(&users) // 通过 &users 推断
  1. 删除操作时(通过传入的模型推断)
1
2
// ✅ Delete 通过 &User{} 知道要删除哪个表
DB.Where("name = ?", "王五").Delete(&User{})

二、Where 必须写在前面吗?

不是必须的!GORM 的方法链顺序很灵活

Where 可以放在不同位置

  1. Where 在前面(最常用)
1
2
3
// 先条件,后操作
DB.Where("age > ?", 18).First(&user)
DB.Where("name = ?", "张三").Delete(&User{})
  1. Where 在后面
1
2
3
// 先指定表,后加条件
DB.Model(&User{}).Where("age > ?", 18).Update("status", 1)
DB.First(&user).Where("age > ?", 18) // 这样也行,但不常见
  1. Where 在中间
1
2
// 条件可以穿插在其他方法之间
DB.Model(&User{}).Select("name, age").Where("age > ?", 18).Order("age desc").Find(&users)

方法链的执行顺序

GORM 的方法链是声明式的,会按照添加顺序构建 SQL,但最终生成的 SQL 是标准的:

1
2
3
4
5
6
7
8
9
10
// 代码顺序
DB.Model(&User{}).
Select("name, age").
Where("age > ?", 18).
Order("age desc").
Limit(10).
Find(&users)

// 最终生成的 SQL(顺序是固定的)
// SELECT name, age FROM users WHERE age > 18 ORDER BY age desc LIMIT 10

三、最佳实践指南

总结:什么时候用什么

操作 写法 原因
查询单条 DB.First(&user, id)DB.Where(...).First(&user) 通过 &user 推断表
查询多条 DB.Find(&users)DB.Where(...).Find(&users) 通过 &users 推断表
更新 DB.Model(&User{}).Where(...).Update(...) 必须用 Model 指定表
删除 DB.Where(...).Delete(&User{}) 通过 &User{} 推断表
Count DB.Model(&User{}).Where(...).Count(&count) 没有结果对象,需 Model 指定表
Joins DB.Model(&User{}).Joins(...).Find(&users) 推荐加上 Model 明确主表
原生 SQL DB.Raw("SELECT ...").Scan(&result) 不需要 Model

快速判断规则

  1. 看有没有结果对象:有 &user/&users 就不用 Model
  2. 看操作类型:Update/Count 等无结果对象的操作需要 Model
  3. 看是否明确:不确定时就加上 Model,不会错

代码示例对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 1. 查询 - 不需要 Model
var user User
DB.Where("name = ?", "张三").First(&user) // ✅
DB.First(&user, "name = ?", "张三") // ✅ 更简洁

// 2. 更新 - 需要 Model
DB.Model(&User{}).Where("name = ?", "张三").Update("age", 26) // ✅
DB.Where("name = ?", "张三").Update("age", 26) // ❌ 错误!

// 3. 删除 - 通过 Delete 参数推断,不需要 Model
DB.Where("name = ?", "张三").Delete(&User{}) // ✅
DB.Delete(&User{}, "name = ?", "张三") // ✅ 更简洁

// 4. 复杂查询 - 推荐加 Model 更清晰
DB.Model(&User{}).
Where("age > ?", 18).
Joins("left join profiles on profiles.user_id = users.id").
Find(&users) // ✅ 推荐

记住这个核心原则:能通过结果对象推断出表名就不需要 Model,否则就需要 Model 明确指定

[up主专用,视频内嵌代码贴在这]