将数据库行读入地图并附加到一片地图

时间:2015-06-01 08:36:52

标签: go

我正在尝试使用这些地图的地图和切片来存储从数据库查询返回的行。但是我在rows.Next()的每次迭代中得到的结果都是查询中同一行的切片。似乎问题与我存储cols的内存位置有关,但直到现在我都无法解决它。

我在这里错过的是什么:

源代码如下:

package main

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

    "fmt"
    "log"

    "reflect"
)
var myMap = make(map[string]interface{})
var mySlice = make([]map[string]interface{}, 0)

func main(){
    fmt.Println("this is my go playground.")

    // DB Connection-
    db, err := sql.Open("postgres", "user=postgres dbname=proj2-dbcruddb-dev password=12345 sslmode=disable")
    if err != nil {
        log.Fatalln(err)
    }
    rows, err := db.Query("SELECT id, username, password FROM userstable")
    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)
        }
        fmt.Println("cols: ", cols)

        for i, col := range cols {
            myMap[colNames[i]] = col
        }
        mySlice = append(mySlice, myMap)

        // Do something with the map
        for key, val := range myMap {
            fmt.Println("Key:", key, "Value:", val, "Value Type:", reflect.TypeOf(val))
        }
        fmt.Println("myMap: ", myMap)
        fmt.Println("mySlice: ", mySlice)

    }
    fmt.Println(mySlice)
}

1 个答案:

答案 0 :(得分:1)

这是因为您在切片中存储的是指向地图而不是地图副本的指针。

来自Go maps in action:

  

地图类型是引用类型,如指针或切片......

由于您在更新它的循环外部创建了地图,因此您将使用新数据覆盖地图中的数据,并且每次都将指向同一地图的指针附加到切片。因此,您可以在切片中获得相同内容的多个副本(是从表中读取的最后一条记录)。

要处理,请将var myMap = make(map[string]interface{})移动到for rows.Next()循环中,以便在每次迭代时创建新地图,然后将其附加到切片。