Gorm Scan to dynamic list 动态列表

发布于 2022-02-06 13:04:02 字数 1463 浏览 1099 评论 0

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

已经忘了多久

文章 0 评论 0

15867725375

文章 0 评论 0

LonelySnow

文章 0 评论 0

走过海棠暮

文章 0 评论 0

轻许诺言

文章 0 评论 0

信馬由缰

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文