Golang运行时无结构生成JSON数据的实现方法
Golang运行时无结构生成JSON数据的实现方法
func queryToJson(db *sql.DB, query string, args …interface{}) ([]byte, error) {
// 一个 JSON 对象数组
// map 的键是字段名
var objects []map[string]interface{}
rows, err := db.Query(query, args...)
if err != nil {
return nil, err
}
for rows.Next() {
// 找出返回了哪些列
// 列名将成为 JSON 对象的字段键
columns, err := rows.ColumnTypes()
if err != nil {
return nil, err
}
// Scan 需要一个指向它所设置值的指针数组
// 这会创建对象并正确设置值
values := make([]interface{}, len(columns))
object := map[string]interface{}{}
for i, column := range columns {
object[column.Name()] = reflect.New(column.ScanType()).Interface()
values[i] = object[column.Name()]
}
err = rows.Scan(values...)
if err != nil {
return nil, err
}
objects = append(objects, object)
}
// 使用缩进,因为我想阅读输出
return json.MarshalIndent(objects, "", "\t")
}
这段代码可以工作。我希望列的顺序与数据库表的字段顺序一致。
更多关于Golang运行时无结构生成JSON数据的实现方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang运行时无结构生成JSON数据的实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言中,使用sql.Rows查询数据库并生成JSON时,保持列顺序确实是一个常见需求。以下是改进后的代码实现,确保JSON字段顺序与数据库表字段顺序一致:
func queryToJson(db *sql.DB, query string, args ...interface{}) ([]byte, error) {
rows, err := db.Query(query, args...)
if err != nil {
return nil, err
}
defer rows.Close()
colTypes, err := rows.ColumnTypes()
if err != nil {
return nil, err
}
colNames := make([]string, len(colTypes))
for i, ct := range colTypes {
colNames[i] = ct.Name()
}
var result []map[string]interface{}
for rows.Next() {
values := make([]interface{}, len(colTypes))
for i := range values {
var v interface{}
values[i] = &v
}
if err := rows.Scan(values...); err != nil {
return nil, err
}
obj := make(map[string]interface{}, len(colTypes))
for i, colName := range colNames {
val := *values[i].(*interface{})
obj[colName] = val
}
result = append(result, obj)
}
if err := rows.Err(); err != nil {
return nil, err
}
return json.MarshalIndent(result, "", "\t")
}
如果需要更严格地保持顺序,可以使用有序的map结构:
import (
"encoding/json"
"database/sql"
"github.com/iancoleman/orderedmap"
)
func queryToOrderedJson(db *sql.DB, query string, args ...interface{}) ([]byte, error) {
rows, err := db.Query(query, args...)
if err != nil {
return nil, err
}
defer rows.Close()
colTypes, err := rows.ColumnTypes()
if err != nil {
return nil, err
}
var result []*orderedmap.OrderedMap
for rows.Next() {
values := make([]interface{}, len(colTypes))
for i := range values {
var v interface{}
values[i] = &v
}
if err := rows.Scan(values...); err != nil {
return nil, err
}
obj := orderedmap.New()
for i, ct := range colTypes {
val := *values[i].(*interface{})
obj.Set(ct.Name(), val)
}
result = append(result, obj)
}
if err := rows.Err(); err != nil {
return nil, err
}
return json.MarshalIndent(result, "", "\t")
}
第一个实现使用标准库,虽然Go的JSON包不保证map的顺序,但在实践中通常按字母顺序输出。第二个实现使用orderedmap第三方库,可以确保JSON字段完全按照数据库列的顺序输出。

