将从数据库查询返回的数据存储到动态创建的通用Go数据类型中

时间:2015-05-29 09:47:44

标签: go

而不是使用struct,它是根据其数据文件数,容量和字段类型预定义的,具有map,可扩展且可包含多种数据类型作为价值,将更有利。例如,在数据库端,对表中列名,列类型或列数的更改不会影响与查询数据库相关的go代码,例如go数据结构,您将rows返回的表单放入数据库查询。

golang sql包或相关驱动程序是否有办法知道数据类型的数据类型,数据库查询返回以定义具有适当数量的字段和类型的struct

如果没有,map如何使用返回的rows列名称来完成此操作,行字段这个map

1 个答案:

答案 0 :(得分:1)

要做到这一点,您必须使用类型为interface{}的值的地图,以便它们可以存储任何类型。如果您还需要列名称,则必须使用rows.Columns()然后提取所有数据和类型。

这将读取表中的所有列,并将值存储在映射中,类型为interface{},列名称为键。在此基础上,您应该能够找到您需要的东西。

var myMap = make(map[string]interface{})
rows, err := db.Query("SELECT * FROM myTable")
defer rows.Close()
if err != nil {
    log.Fatal(err)
}
colNames, err := rows.Columns()
if err != nil {
    log.Fatal(err)
}
cols := make([]interface{}, len(colNames))
colPtrs := make([]interface{}, len(colNames))
for i := 0; i < len(colNames); i++ {
    colPtrs[i] = &cols[i]
}
for rows.Next() {
    err = rows.Scan(colPtrs...)
    if err != nil {
        log.Fatal(err)
    }
    for i, col := range cols {
        myMap[colNames[i]] = col
    }
    // Do something with the map
    for key, val := range myMap {
        fmt.Println("Key:", key, "Value Type:", reflect.TypeOf(val))
    }
}

使用反射包,您可以根据需要获取每列的类型,如末尾的循环所示。或者您可以使用type switch来提取类型。

以上是通用的,可以使用任意数量的列和类型。