查询

1 查找单个对象

GORM 提供了 FirstTakeLast 方法,以便从数据库中检索单个对象。当查询数据库时它添加了 LIMIT 1 条件,且没有找到记录时,它会返回 ErrRecordNotFound 错误

// 获取第一条记录(主键升序)
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;

// 获取一条记录,没有指定排序字段
db.Take(&user)
// SELECT * FROM users LIMIT 1;

// 获取最后一条记录(主键降序)
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;

result := db.First(&user)
result.RowsAffected // 返回找到的记录数
result.Error        // returns error or nil

// 检查 ErrRecordNotFound 错误
errors.Is(result.Error, gorm.ErrRecordNotFound)

如果你想避免ErrRecordNotFound错误,你可以使用Find,比如db.Limit(1).Find(&user)Find方法可以接受struct和slice的数据。

First and Last 方法会按主键排序找到第一条记录和最后一条记录 (分别)。 只有在目标 struct 是指针或者通过 db.Model() 指定 model 时,该方法才有效。 此外,如果相关 model 没有定义主键,那么将按 model 的第一个字段进行排序。

2 根据主键检索

如果主键是数字类型,您可以使用 内联条件arrow-up-right 来检索对象。 当使用字符串时,需要额外的注意来避免SQL注入

当目标对象有一个主键值时,将使用主键构建查询条件,例如:

如果使用 gorm 的特定字段类型(例如 gorm.DeletedAt),它将运行不同的查询来检索对象。

3 检索全部对象

4 条件

4.1 string条件

如果对象设置了主键,条件查询将不会覆盖主键的值,而是用 And 连接条件。 例如:

这个查询将会给出record not found错误 所以,在你想要使用例如 user 这样的变量从数据库中获取新值前,需要将例如 id 这样的主键设置为nil。

4.2 Struct&Map条件

当使用结构体进行查询时,GORM只会查询非零字段,这意味着如果您的字段值是0、''、false或其他零值,则不会用于构建查询条件,例如:

要在查询条件中包含零值,您可以使用一个map,这将包括所有键值作为查询条件,例如:

4.3 指定结构体查询字段

在用结构体进行搜索时,您可以通过传递相关字段名或dbname到Where()中,来指定结构体中哪些特定的值用于查询条件,例如:

4.4 内联条件

查询条件可以以类似Where的方式内联到First和Find等方法中。

4.5 Not条件

构建Not条件,跟Where类似

4.6 Or条件

5 选择特定字段

Select 允许您指定要从数据库中检索的字段。否则,GORM 将默认选择所有字段。

6 排序

在从数据库检索记录时指定排序

7 Limit&Offset

Limit指定要检索的最大记录数,Offset指定在开始返回记录之前要跳过的记录数

8 Group By & Having

9 Distinct

从模型中选择不同的值

10 Joins

指定连接条件

10.1 预加载

可以使用Joins预加载关联

10.2 Join子表

可以使用Join连接一个派生表

11 Scan

将结果表扫到结构体中,跟Find类似

12 相关方法

12.1 func (db *DB) First(dest interface{}, conds ...interface{}) (tx *DB)

  • 功能:获取按主键升序排序的第一条记录

  • 排序规则:

    • 默认按主键升序排序 (ORDER BY primary_key ASC)

    • 非自增主键可能导致意外结果

    • 没有主键使用第一个字段进行排序

12.2 func (db *DB) Take(dest interface{}, conds ...interface{}) (tx *DB)

  • 功能:获取任意一条记录(无排序)

  • 不指定排序规则 (LIMIT 1)

  • 数据库依赖实现,通常返回最早插入的记录

12.3 func (db *DB) Last(dest interface{}, conds ...interface{}) (tx *DB)

  • 功能:获取按主键降序排序的第一条记录

  • 排序规则:跟 Frist 类似

以上三个单记录查询会在未找到记录时返回 ErrRecordNotFound 错误。

12.4 func (db *DB) Find(dest interface{}, conds ...interface{}) (tx *DB)

  • 功能:查询多条记录并填充到切片中

  • dest必须是指向切片的指针

  • 空结果返回空切片,不会返回错误

12.5 func (db *DB) Where(query interface{}, args ...interface{}) (tx *DB)

  • 功能:添加Where条件

  • 注意:查询应都用Where进行参数化查询,避免SQL注入风险

  • 多Where条件组合会用 And 进行连接

12.6 func (db *DB) Order(value interface{}) (tx *DB)

  • 功能:指定结果排序方式

  • 多个一起使用后面的会覆盖前面的排序指定

12.7 func (db *DB) Scan(dest interface{}) (tx *DB)

  • 功能:将查询结果映射到指定目标(结构体、map 或基础类型),不依赖模型定义

  • 特典:

    1. ​灵活映射​​:

      • 支持结构体、map、基础类型及其切片

      • 不要求目标类型是 GORM 模型

    2. ​结果处理​​:

      • 查询无结果时,目标变量​​保持原值不变​

      • 字段名自动匹配(不区分大小写,蛇形命名转换)

    3. ​链式调用​​:

      • 需配合 SelectTableRaw等方法使用

最后更新于