Golang中如何将查询结果存储到maps中

Golang中如何将查询结果存储到maps中 如何将查询结果存储在映射中

2 回复

这是一个相当宽泛的问题。不过,从通用方法的角度来看,SQLX 有一个 MapScan 函数可能对你有用:

func MapScan(r ColScanner, dest map[string]interface{}) error {
	// ignore r.started, since we needn't use reflect for anything.
	columns, err := r.Columns()
	if err != nil {
		return err
	}

	values := make([]interface{}, len(columns))
	for i := range values {
		values[i] = new(interface{})
	}

总而言之就是:返回一个行迭代器,然后遍历它并创建你的映射。我不太清楚你是想为每一行创建一个映射,还是想创建一个包含所有来自单列值的映射,或者其他什么。但是——这应该能让你开始。

更多关于Golang中如何将查询结果存储到maps中的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中将查询结果存储到maps中,可以通过以下方式实现:

1. 使用结构体标签映射到map

package main

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "log"
    _ "github.com/go-sql-driver/mysql"
)

type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func queryToMap(db *sql.DB) ([]map[string]interface{}, error) {
    rows, err := db.Query("SELECT id, name, age FROM users")
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    columns, err := rows.Columns()
    if err != nil {
        return nil, err
    }

    var results []map[string]interface{}
    
    for rows.Next() {
        values := make([]interface{}, len(columns))
        valuePtrs := make([]interface{}, len(columns))
        
        for i := range columns {
            valuePtrs[i] = &values[i]
        }
        
        if err := rows.Scan(valuePtrs...); err != nil {
            return nil, err
        }
        
        rowMap := make(map[string]interface{})
        for i, col := range columns {
            val := values[i]
            b, ok := val.([]byte)
            if ok {
                rowMap[col] = string(b)
            } else {
                rowMap[col] = val
            }
        }
        results = append(results, rowMap)
    }
    
    return results, nil
}

2. 使用sqlx库简化操作

package main

import (
    "fmt"
    "github.com/jmoiron/sqlx"
    _ "github.com/go-sql-driver/mysql"
)

func queryToMapWithSqlx() {
    db, err := sqlx.Open("mysql", "user:password@/dbname")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // 查询到map切片
    var results []map[string]interface{}
    err = db.Select(&results, "SELECT * FROM users")
    if err != nil {
        log.Fatal(err)
    }

    // 查询单行到map
    result := make(map[string]interface{})
    err = db.QueryRowx("SELECT id, name FROM users WHERE id = ?", 1).MapScan(result)
    if err != nil {
        log.Fatal(err)
    }
}

3. 使用结构体切片转换为map

package main

import (
    "database/sql"
    "encoding/json"
    "fmt"
)

func structSliceToMap(users []User) []map[string]interface{} {
    var result []map[string]interface{}
    
    for _, user := range users {
        // 使用JSON转换
        var m map[string]interface{}
        b, _ := json.Marshal(user)
        json.Unmarshal(b, &m)
        result = append(result, m)
    }
    
    return result
}

// 或者手动转换
func manualStructToMap(users []User) []map[string]interface{} {
    var result []map[string]interface{}
    
    for _, user := range users {
        m := map[string]interface{}{
            "id":   user.ID,
            "name": user.Name,
            "age":  user.Age,
        }
        result = append(result, m)
    }
    
    return result
}

4. 使用反射动态处理

package main

import (
    "database/sql"
    "reflect"
)

func queryToDynamicMap(db *sql.DB, query string, args ...interface{}) ([]map[string]interface{}, error) {
    rows, err := db.Query(query, args...)
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    cols, _ := rows.Columns()
    colTypes, _ := rows.ColumnTypes()
    
    var results []map[string]interface{}
    
    for rows.Next() {
        values := make([]interface{}, len(cols))
        for i := range values {
            var v interface{}
            values[i] = &v
        }
        
        if err := rows.Scan(values...); err != nil {
            return nil, err
        }
        
        rowMap := make(map[string]interface{})
        for i, col := range cols {
            val := reflect.ValueOf(values[i]).Elem().Interface()
            rowMap[col] = val
        }
        results = append(results, rowMap)
    }
    
    return results, nil
}

5. 主函数示例

func main() {
    db, err := sql.Open("mysql", "user:password@/dbname")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // 方法1:使用通用查询函数
    results, err := queryToMap(db)
    if err != nil {
        log.Fatal(err)
    }
    
    for _, row := range results {
        fmt.Printf("ID: %v, Name: %v, Age: %v\n", 
            row["id"], row["name"], row["age"])
    }
    
    // 方法2:查询特定条件到map
    row := make(map[string]interface{})
    err = db.QueryRow("SELECT id, name FROM users WHERE id = ?", 1).
        Scan(&row["id"], &row["name"])
    if err != nil {
        log.Fatal(err)
    }
}

这些方法提供了不同场景下将查询结果存储到maps中的解决方案,可以根据具体需求选择合适的方法。第一种方法是最通用的,适用于任何SQL查询场景。

回到顶部