golang,go,博客,开源,编程
在使用 gorm
进行数据库操作时,Find
和 Scan
都是用来查询数据的,但它们有一些重要的区别,特别是在查询的结果存储和数据类型匹配方面。
Find
方法Find
是 gorm
中常用的查询方法,用于获取查询结果,并将结果映射到一个结构体或结构体切片中。Find
会根据模型的字段来映射查询结果,因此通常会返回完全匹配的字段。
var users []User
db.Find(&users) // 查询所有用户
在这个例子中,Find
会查询所有用户,并将查询结果存储到 users
切片中。User
结构体的字段会与数据库表的列进行映射。如果表中存在额外的字段或字段类型不匹配,gorm
会自动进行处理。
Find
会自动将数据库中的列名与结构体字段名匹配,使用反射将数据库字段填充到结构体中。gorm
会进行类型转换。Find
主要用于查询数据并将结果映射到结构体中,通常不需要额外处理。Find
适用场景: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
适用场景:db.Raw
)时,将查询结果扫描到结构体中。Scan
。特性 | Find | Scan |
---|---|---|
自动映射字段 | 是 | 否 |
用途 | 查询数据并映射到结构体 | 将查询结果扫描到结构体 |
适用场景 | 用于查询结果直接与模型映射 | 用于自定义 SQL 查询或结构体不匹配的情况 |
是否支持原始 SQL | 否(主要是针对 GORM 的模型查询) | 是(可以与原始 SQL 一起使用) |
结果处理 | 自动处理字段和类型映射 | 手动扫描查询结果 |
假设我们有以下 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
一样自动映射字段名,它只会根据查询结果的列和你传入的结构体字段进行扫描。
Find
更适用于标准的查询操作,它会自动将查询结果映射到模型的结构体字段中,通常用于模型和表之间的直接映射。Scan
更加灵活,适用于复杂的查询或原始 SQL 查询,允许你将查询结果扫描到自定义结构体或模型中。