Gorm Scan to dynamic list 动态列表
https://kylewbanks.com/blog/query-result-to-map-in-golang
与上面的动态 select 类似,我们写代码的时候还不确定 select 了几个数,但后面需要 scan 出来,标准的 scan 语句是
var db *gorm.DB
var v1, v2, v3 int32
err := db.Row().Scan(&v1, &v2, &v3)
即 scan 内部的参数是确定的,但对于动态的 select,我们只能在运行的时候才能确定它的数量,这时怎么写 gorm 的 scan 语句呢?
第一反应可能想到,上面的几个数都是 int32 类型,所以 gorm 是否支持直接把所有结果扫到一个列表中呢:
var db *gorm.DB
res := make([]int32, len(conditionList))
err := db.Row().Scan(res)
如果这样写,会收到类似 index out of range
的报错,因为 res 变量实际上还是只能接收结果集中的一列,其他列是没有指定变量来接收的
查了一下,发现 scan 是支持扫到一个interface的列表的:
var db *gorm.DB
res := make([]interface{}, len(conditionList))
err := db.Row().Scan(res...)
但是,如果仅仅这样写,运行时又会有另一个报错:destination not a pointer
,大意就是 res 里的元素并不是指针类型。所以我们需要把它的每个元素变成指针,就 OK 了:
var db *gorm.DB
cols := make([]int32, len(conditionList))
scanRes := make([]interface{}, len(conditionList))
for i := range cols {
scanRes[i] = &cols[i]
}
err := db.Row().Scan(res...)
最后再把 scanRes 里面的值读出来:
res := make([]int32, 0)
for index := range scanRes {
colVal, ok := scanRes[index].(*int32)
if ok {
res = append(res, *colVal)
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论