golang,go,博客,开源,编程

gorm Find()与Scan()的区别

Published on with 0 views and 0 comments

在使用 gorm 进行数据库操作时,FindScan 都是用来查询数据的,但它们有一些重要的区别,特别是在查询的结果存储和数据类型匹配方面。

1. Find 方法

Findgorm 中常用的查询方法,用于获取查询结果,并将结果映射到一个结构体或结构体切片中。Find 会根据模型的字段来映射查询结果,因此通常会返回完全匹配的字段。

示例:

var users []User
db.Find(&users)  // 查询所有用户

在这个例子中,Find 会查询所有用户,并将查询结果存储到 users 切片中。User 结构体的字段会与数据库表的列进行映射。如果表中存在额外的字段或字段类型不匹配,gorm 会自动进行处理。

特点:

  • Find 会自动将数据库中的列名与结构体字段名匹配,使用反射将数据库字段填充到结构体中。
  • 如果结果列与结构体字段的类型不匹配,gorm 会进行类型转换。
  • 如果查询结果不包含某些字段,它会使用结构体中默认的零值填充。
  • Find 主要用于查询数据并将结果映射到结构体中,通常不需要额外处理。

Find 适用场景:

  • 当你已经有一个结构体,并且希望将查询结果自动映射到该结构体时。
  • 适用于常见的查询和模型结构之间的一对一映射。

2. Scan 方法

Scan 用于将查询结果扫描到结构体中,但不同于 Find,它的使用场景更灵活,适用于更加复杂的查询。Scan 方法不会进行自动的结构体字段和数据库列的匹配。你需要手动提供一个结构体,或者传入一个支持赋值的类型。

示例:

var users []User
db.Raw("SELECT * FROM users WHERE age > ?", 30).Scan(&users)

在这个例子中,Scan 用于从原始 SQL 查询的结果中扫描数据并将其存储到 users 切片中。与 Find 不同,Scan 可以直接对查询结果进行控制,例如对某些特定的列进行查询或自定义查询逻辑。

特点:

  • Scan 更加灵活,可以用于自定义 SQL 查询,甚至支持将查询结果扫描到结构体的某些字段中。
  • Scan 不会自动将字段与结构体字段进行匹配,它需要你自己确保类型匹配。
  • 适用于需要更高自定义的场景,比如执行 Raw SQL 查询时。
  • Scan 可以用于查询结果并将其扫描到非模型的结构体,或仅部分字段。

Scan 适用场景:

  • 适用于执行原始 SQL 查询(例如 db.Raw)时,将查询结果扫描到结构体中。
  • 当你需要执行复杂的查询,并且不想或者不能完全映射到模型时,可以使用 Scan

3. 区别总结

特性FindScan
自动映射字段
用途查询数据并映射到结构体将查询结果扫描到结构体
适用场景用于查询结果直接与模型映射用于自定义 SQL 查询或结构体不匹配的情况
是否支持原始 SQL否(主要是针对 GORM 的模型查询)是(可以与原始 SQL 一起使用)
结果处理自动处理字段和类型映射手动扫描查询结果

4. 示例对比

假设我们有以下 User 结构体:

type User struct {
    ID   uint
    Name string
    Age  int
}

Find 示例

var users []User
db.Find(&users)  // 查询所有用户

Find 会自动将查询结果映射到 users 切片的结构体中,假设查询结果返回了 id, name, age 列,gorm 会自动把这些字段赋值给 User 结构体的对应字段。

Scan 示例

var users []User
db.Raw("SELECT id, name, age FROM users WHERE age > ?", 30).Scan(&users)

Scan 中,我们显式地执行了一个原始 SQL 查询。Scan 会将查询结果扫描到 users 切片中。需要注意,Scan 不会像 Find 一样自动映射字段名,它只会根据查询结果的列和你传入的结构体字段进行扫描。

5. 总结

  • Find 更适用于标准的查询操作,它会自动将查询结果映射到模型的结构体字段中,通常用于模型和表之间的直接映射。
  • Scan 更加灵活,适用于复杂的查询或原始 SQL 查询,允许你将查询结果扫描到自定义结构体或模型中。

标题:gorm Find()与Scan()的区别
作者:mooncakeee
地址:http://blog.dd95828.com/articles/2025/01/07/1736227183722.html
联系:scotttu@163.com