将数据库行读入地图并附加到地图切片 [英] Reading database rows into map and appending to a slice of maps

查看:113
本文介绍了将数据库行读入地图并附加到地图切片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用地图和这些地图片来存储从数据库查询返回的行。但是我在每次迭代中得到的结果。next()和final是查询中同一行的切片。看起来问题与存储地点相同,我存储 cols ,但直到现在我还无法解决它。



我在这里遗漏的是什么:



源代码如下:

<$ p















$ b $ $ bfmt
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连接 -
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)
推迟行.close()
if err!= nil {
log.Fatal(err)
}

colName s,err:= rows.Columns()
if err!= nil {
log.Fatal(err)
}
cols:= make([] interface {}, len(colNames))
colPtrs:= make([] interface {},len(colNames))
for i:= 0;我< LEN(colNames); (){
err = rows.Scan(colPtrs ..) )
if err!= nil {
log.Fatal(err)
}
fmt.Println(cols:,cols)

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

// Do一些地图
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)
}


解决方案

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



来自开始使用地图:


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


由于您在循环外部创建了更新地图的地图,因此您会使用新数据覆盖地图中的数据,并将指针添加到相同的地图每次切片。因此,您可以在切片中获取同一事物的多个副本(作为从表格中读取的最后一条记录)。



要处理,请移动 var myMap对于rows.Next()循环,make(map [string] interface {})放入中,这样每次迭代都会创建一个新地图,然后附加到切片上。


I am trying to use maps and slice of those maps to store rows returned from a database query. But what I get in every iteration of the rows.Next() and in final is the slice of the one same row from the query. It seems the problem is related to the memory place being same I store the cols, yet I could not resolve it until now.

What is the thing am I missing here:

The source code is as follows:

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)
}

解决方案

This is because what you are storing in the slice is a pointer to a map rather than a copy of the map.

From Go maps in action:

Map types are reference types, like pointers or slices...

Since you create the map outside the loop that updates it, you keep overwriting the data in the map with new data and are appending a pointer to the same map to the slice each time. Thus you get multiple copies of the same thing in your slice (being the last record read from your table).

To handle, move var myMap = make(map[string]interface{}) into the for rows.Next() loop so a new map is create on each iteration and then appended to the slice.

这篇关于将数据库行读入地图并附加到地图切片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆