我想从第 3 方 API 中获取一个表示对象的 JSON 字符串,并将其插入到 MySQL 表中。 JSON 对象属性与表字段一对一匹配。此表/JSON 对象中有数百列。并且随时会插入几十行。
我不想做一个巨大的结构。但如果我需要,那么我宁愿不使用 db.Prepare()
带有数百个“?”的 INSERT 语句。但是,如果必须的话,我宁愿不必编写带有数百个参数的 stmt.Exec()
。
在 golang 中有没有好的方法来做到这一点?还是效率极低?
最佳答案
使用以下给定的有效数据库字段名称 fieldNames
和 JSON 数据 data
:
var j map[string]interface{}
if err := json.Unmarshal(data, &j); err != nil {
// handle error
}
var names []string
var inserts []string
var values []interface{}
for _, n := range fieldNames {
if v, ok := j[n]; ok {
names = append(names, n)
inserts = append(inserts, "?")
values = append(values, v)
}
}
statement := "insert into yourTable (" +
strings.Join(names, ", ") +
") values (" + strings.Join(inserts, ", ") + ")"
err := db.Exec(statement, values...)
为避免 SQL 注入(inject)攻击,使用已知列名的 slice 非常重要。
您可以查询数据库以创建 fieldNames
slice 。参见 Get table column names in MySQL?对于所需的查询。
如果列名和 JSON 名称不同,则将 slice 替换为一个映射,其中键是列名,值是 JSON 名称:
fieldNames := map[string]string{
"column1": "json1",
... and so on
}
var j map[string]interface{}
if err := json.Unmarshal(data, &j); err != nil {
// handle error
}
var names []string
var inserts []string
var values []interface{}
for dbName, jsonName := range fieldNames {
if v, ok := j[jsonName]; ok {
names = append(names, dbName)
inserts = append(inserts, "?")
values = append(values, v)
}
}
statement := "insert into yourTable (" +
strings.Join(names, ", ") +
") values (" + strings.Join(inserts, ", ") + ")"
err := db.Exec(statement, values...)
关于mysql - 如何将 JSON 对象转换为 MySQL 行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54155668/