Gorm 中 Scan 和 Find 的区别

the difference of Gorm scan and find

foreversmart write on 2021-02-10
我们可以先看 Scan 和 Find 在 Gorm 中的接口定义
FInd
Go
Execute 方法会执行 Query() callback 中的回调函数,回调函数中是它真正的执行逻辑,下面是 Query Callback 的初始注册函数,:
Go
Query 函数里面是具体执行的逻辑:
Go
Scan 方法
Go
这个方法里面主要有两个逻辑一个是获取对应的结果行 rows, err := tx.Rows() 另一个是对结果行做扫描反序列化 tx.ScanRows(rows, dest)
首先来看下 rows, err := tx.Rows()
Go
它的主要执行逻辑是 tx.callbacks.Row().Execute(tx) ,Execute 方法会执行 Row callback 中的回调函数,回调函数中是它真正的执行逻辑,下面是 Row 的初始化回调函数
Go
主要的逻辑在 RowQuery 函数中
Go
这里我们可以看到这个 RowQuery 函数和 Find 回调的 Query 函数逻辑几乎差不多,唯一的差别就是将结果 rows 赋值给了 Statement 里面的 Dest
Scan 方法中的另一个操作是执行 tx.ScanRows(rows, dest)
Go
这个方法将 Statement 里面的 Dest 值改为 Scan 方法中的 Dest 结构,然后执行 Scan 函数 这个和 Find 函数 Query() 回调函数中的逻辑是一样的。
那么我们最后来看看到底 Scan 方法和 Find 方法有什么不同:
Find 在调用 Execute() 然后执行回调函数前执行了 tx.Statement.Dest = dest 修改了语句的目标 Struct,而 Scan 没有,Scan 方法是在执行完 Execute() 里面的回调函数后,在 ScanRows 方法里面调用tx.Statement.Dest = dest 。会有一个结果就是 Execute 方法会调用Parse 方法解析 Dest 或 Model 中的 struct 来得到数据库表的 Schema,而显然 Scan 方法是解析不到的。所以使用 Scan 方法的时候需要我们显示指定数据库的表名。
回调函数注册的不一样,Find 函数支持更多的 Callback 注入
Go

「真诚赞赏,手留余香」

Foreversmart

真诚赞赏,手留余香

使用微信扫描二维码完成支付