首页 >后端开发 >Golang >如何使用反射调用数据库/SQL Rows.Scan() 可变参数函数?

如何使用反射调用数据库/SQL Rows.Scan() 可变参数函数?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-12-05 09:56:11755浏览

How to Use Reflection to Call the Database/SQL Rows.Scan() Variadic Function?

通过反射调用 Scan() 变量函数

Rows.Scan() 函数提供了一种从数据库检索数据的便捷方法询问。然而,它使用可变数量的指针作为其参数,这对于使用反射来合并可能具有挑战性。 考虑以下场景:

您希望使用从查询获得的值动态填充切片并利用 Rows.Scan() 提取数据。在这种情况下,您需要确定列数并创建一个切片来存储值。

常见陷阱:
尝试使用反射来调用Scan() 函数可能会导致意外结果。这是因为 Rows.Scan() 需要指向值的指针,并且简单地传递一个 interface{} 值的切片将导致零引用。

解决方案:

为了通过反射成功调用 Scan(),采用了双切片方法。第一个切片values保存实际数据,第二个切片valuesPtrs包含指向values中每个元素的指针。

对于查询结果中的每一列,valuesPtrs中的指针映射到相应的元素在价值观中。随后,可以使用valuesPtrs作为参数来调用Rows.Scan(),从而有效地填充值。

工作示例:

package main

import (
    "fmt"
    _ "github.com/lib/pq"
    "database/sql"
)

func main() {
    db, _ := sql.Open(
        "postgres",
        "user=postgres dbname=go_testing password=pass sslmode=disable")

    rows, _ := db.Query("SELECT * FROM _user;")

    columns, _ := rows.Columns()
    count := len(columns)
    values := make([]interface{}, count)
    valuesPtrs := make([]interface{}, count)

    for rows.Next() {
        for i := range columns {
            valuesPtrs[i] = &values[i]
        }

        rows.Scan(valuesPtrs...)

        for i, col := range columns {
            val := values[i]

            b, ok := val.([]byte)
            var v interface{}
            if (ok) {
                v = string(b)
            } else {
                v = val
            }

            fmt.Println(col, v)
        }
    }
}

在此示例中,rows.Scan()。 Scan() 使用指针切片 valuePtrs 调用,用检索到的数据填充值切片。然后循环打印每个列名称及其相应的值。

以上是如何使用反射调用数据库/SQL Rows.Scan() 可变参数函数?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn