问题:Golang 中的动态 SQL 选择查询
我正在尝试使用 database/sql 和 mysql 驱动程序构建 API,它将根据 URL 参数读取数据。
像这样的东西
myapi.com/users?columns=id,first_name,last_name,country&sort=desc&sortColumn=last_name&limit=10&offset=20
我知道如何获取所有列或仅在 struct 中定义的特定列。但我想知道是否可以从 url 获取列,而不是预定义的 struct 将其保存到映射,而不仅仅是扫描这些列。
countryScan
我不需要特定的代码,只需要一些指导,因为我正在学习 Go 并且我的背景是 PHP,这更容易做到。
更新
感谢答案,我有部分工作解决方案。
这是代码:
cols := []string{"id", "first_name", "last_name"}
vals := make([]interface{}, len(cols))
w := map[string]interface{}{"id": 105}
var whereVal []interface{}
var whereCol []string
for k, v := range w {
whereVal = append(whereVal, v)
whereCol = append(whereCol, fmt.Sprintf("%s = ?", k))
}
for i := range cols {
vals[i] = new(interface{})
}
err := db.QueryRow("SELECT "+strings.Join(cols, ",")+" FROM users WHERE "+strings.Join(whereCol, " AND "), whereVal...).Scan(vals...)
if err != nil {
fmt.Println(err)
}
b, _ := json.Marshal(vals)
fmt.Println(string(b))
SELECT id, first_name, last_name FROM users WHERE id = 105;
但是如何将数据输出到正确的 json 对象?现在它像这样打印出用 base64 编码的字符串。
[105,"Sm9obm55","QnJhdm8="]
解答
Scan[]byte
所以你必须为你的列分配一个类型,如果你想要正确的 json,然后将键分配给值。
在您的示例中,可以这样做:
cols := []string{"id", "first_name", "last_name"}
vals := make([]interface{}, len(cols))
result := make(map[string]interface{}, len(cols))
for i, key := range cols {
switch key {
case "id", "status":
vals[i] = new(int)
default:
vals[i] = new(string)
}
result[key] = vals[i]
}
b, _ := json.Marshal(result)
fmt.Println(string(b))
cols
nilstringgopkg.in/guregu/null.v3null.Stringnull
例如:
for i, key := range cols {
switch key {
case "id", "status":
vals[i] = new(int)
case "updated_at", "created_at":
vals[i] = new(null.Time)
default:
vals[i] = new(null.String)
}
result[key] = vals[i]
}