Golang中如何实现map和json的字段自动排序
Golang中如何实现map和json的字段自动排序 我遇到了一个问题。 我从数据库中获取行数据并将其写入映射接口。 然后将其转换为JSON并发送给客户端。
我需要保持数据库中指定的字段顺序。
以下是一段代码片段:
rows, _ := db.Query("SELECT * FROM table")
cols, _ := rows.Columns()
defer rows.Close()
d:= make([]map[string]interface{}, 0)
for rows.Next() {
columns := make([]interface{}, len(cols))
columnPointers := make([]interface{}, len(cols))
for i, _ := range columns {
columnPointers[i] = &columns[i]
}
rows.Scan(columnPointers...)
m := make(map[string]interface{})
for i, colName := range cols {
val := columnPointers[i].(*interface{})
m[colName] = *val
}
d = append(d, m)
}
fmt.Println(d[100])
jsData, _ := json.Marshal(d)
w.Header().Set("Content-Type", "application/json")
w.Write(jsData)
更多关于Golang中如何实现map和json的字段自动排序的实战教程也可以访问 https://www.itying.com/category-94-b0.html
如果字段名称是用西里尔字母并带有空格书写的呢?
更多关于Golang中如何实现map和json的字段自动排序的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
为什么这在Go语言这边会是个问题呢?也许是在尝试将它们用作数据库列名时会出现问题……
因为我需要通过循环遍历所有数据来将数据填入动态表格。该表格包含约100个字段。
手动完成这项工作是不现实的。
igaisin:
我需要保持数据库中指定的字段顺序。
为什么?
Go 语言的 map 和 JSON 对象都不是有序的。{"a": 1, "b": 2} 和 {"b": 2, "a": 1} 在 JSON 中是等效的。
正确的方式是拥有一些额外的数据点来描述字段的顺序,例如一个字符串列表。遍历该列表并使用它来访问映射/对象中的字段。
// 代码示例
func main() {
fields := []string{"field1", "field2", "field3"}
data := map[string]interface{}{
"field1": "value1",
"field2": "value2",
"field3": "value3",
}
for _, field := range fields {
fmt.Println(data[field])
}
}
尝试将您检索的数据作为"本地"变量存储在YottaDB中。数据始终是排序的。更多信息请参阅https://docs.yottadb.com/MultiLangProgGuide/goprogram.html。值得一提的是,YottaDB还拥有分层键值数据库/持久化引擎(称为"全局"变量),但如果您已有数据库,可以直接将检索到的数据存储在YottaDB中而无需使用持久化引擎。
郑重声明:我负责领导YottaDB(https://yottadb.com & https://gitlab.com/YottaDB)。
此致 – Bhaskar
在Golang中,map[string]interface{}的键在JSON序列化时默认是无序的。要维持从数据库查询得到的字段顺序,可以使用有序的数据结构替代普通的map。以下是几种解决方案:
方案1:使用切片存储字段顺序
type OrderedMap struct {
Keys []string
Values map[string]interface{}
}
func (om *OrderedMap) MarshalJSON() ([]byte, error) {
var buf bytes.Buffer
buf.WriteString("{")
for i, key := range om.Keys {
if i > 0 {
buf.WriteString(",")
}
keyBytes, _ := json.Marshal(key)
buf.Write(keyBytes)
buf.WriteString(":")
valBytes, _ := json.Marshal(om.Values[key])
buf.Write(valBytes)
}
buf.WriteString("}")
return buf.Bytes(), nil
}
// 使用示例
rows, _ := db.Query("SELECT * FROM table")
cols, _ := rows.Columns()
defer rows.Close()
d := make([]OrderedMap, 0)
for rows.Next() {
columns := make([]interface{}, len(cols))
columnPointers := make([]interface{}, len(cols))
for i := range columns {
columnPointers[i] = &columns[i]
}
rows.Scan(columnPointers...)
m := OrderedMap{
Keys: cols,
Values: make(map[string]interface{}),
}
for i, colName := range cols {
val := columnPointers[i].(*interface{})
m.Values[colName] = *val
}
d = append(d, m)
}
jsData, _ := json.Marshal(d)
w.Header().Set("Content-Type", "application/json")
w.Write(jsData)
方案2:使用第三方库(推荐)
安装有序map库:
go get github.com/iancoleman/orderedmap
import "github.com/iancoleman/orderedmap"
rows, _ := db.Query("SELECT * FROM table")
cols, _ := rows.Columns()
defer rows.Close()
d := make([]*orderedmap.OrderedMap, 0)
for rows.Next() {
columns := make([]interface{}, len(cols))
columnPointers := make([]interface{}, len(cols))
for i := range columns {
columnPointers[i] = &columns[i]
}
rows.Scan(columnPointers...)
m := orderedmap.New()
for i, colName := range cols {
val := columnPointers[i].(*interface{})
m.Set(colName, *val)
}
d = append(d, m)
}
jsData, _ := json.Marshal(d)
w.Header().Set("Content-Type", "application/json")
w.Write(jsData)
方案3:使用结构体切片(如果字段固定)
type Field struct {
Key string `json:"key"`
Value interface{} `json:"value"`
}
rows, _ := db.Query("SELECT * FROM table")
cols, _ := rows.Columns()
defer rows.Close()
d := make([][]Field, 0)
for rows.Next() {
columns := make([]interface{}, len(cols))
columnPointers := make([]interface{}, len(cols))
for i := range columns {
columnPointers[i] = &columns[i]
}
rows.Scan(columnPointers...)
fields := make([]Field, len(cols))
for i, colName := range cols {
val := columnPointers[i].(*interface{})
fields[i] = Field{
Key: colName,
Value: *val,
}
}
d = append(d, fields)
}
jsData, _ := json.Marshal(d)
w.Header().Set("Content-Type", "application/json")
w.Write(jsData)
推荐使用方案2的orderedmap库,它专门为解决这类问题设计,使用简单且性能良好。

