GO – 解析 MySQL 中的 JSON 为字符串数组

huangapple go评论78阅读模式
英文:

GO - parse mysql json to array of strings

问题

有这样的结构体:

Programs struct {
    ID                  int      `json:"id"`
    ShortName           string   `json:"short_name"`
    ProgramPoints       float64  `json:"program_points"`
    Countries           []string `json:"countries"`
}

countries是一个包含国家数组的JSON列["US","GB"]
解析:

stmt, err := db.Query(sql)
err = stmt.Scan(
    &program.ID,
    &program.ShortName,
    &program.ProgramPoints,
    &program.Countries)

出现错误
unsupported Scan, storing driver.Value type []uint8 into type *[]string
我找到了将JSON对象解析为结构体的方法,但不是数组。提前感谢任何帮助。

英文:

There is such struct:

Programs struct {
	ID                  int      `json:"id"`
	ShortName           string   `json:"short_name"`
	ProgramPoints       float64  `json:"program_points"`
	Countries           []string `json:"countries"`
}

The column countries is JSON column which contains array of countries ["US","GB"]
Parsing:

    stmt, err := db.Query(sql)
    err = stmt.Scan(
    		&program.ID,
    		&program.ShortName,
    		&program.ProgramPoints,
		    &program.Countries)

Has error
unsupported Scan, storing driver.Value type []uint8 into type *[]string
I've found the way how to parse JSON object to struct but not array. Thx in advance for any help

答案1

得分: 2

所以,既然你希望从数据库中获取JSON值并自动进行(反)解组,你需要为此创建一个类型:

type Programs struct {
    ID                  int       `json:"id"`
    ShortName           string    `json:"short_name"`
    ProgramPoints       float64   `json:"program_points"`
    Countries           Countries `json:"countries"`
}

type Countries []string

func (c Countries) Value() (driver.Value, error) {
    return json.Marshal(c) // 返回JSON编组后的值
}

func (c *Countries) Scan(v interface{}) error {
    switch tv := v.(type) {
    case []byte:
        return json.Unmarshal(tv, &c) // 反解组
    case []uint8:
        return json.Unmarshal([]byte(tv), &c) // 无法记住具体细节,但可能需要这样做
    }
    return errors.New("不支持的类型")
}

这样就可以处理stmt.Scan的内容了。

英文:

So seeing as you're wanting the JSON value to come from the DB and be (un)marshaled automagically, you'll need to create a type for that:

type Programs struct {
	ID                  int       `json:"id"`
	ShortName           string    `json:"short_name"`
	ProgramPoints       float64   `json:"program_points"`
	Countries           Countries `json:"countries"`
}

type Countries []string

func (c Countries) Value() (driver.Value, error) {
    return json.Marshal(c) // return json marshalled value
}

func (c *Countries) Scan(v interface{}) error {
    switch tv := v.(type) {
    case []byte:
        return json.Unmarshal(tv, &c) // unmarshal
    case []uint8:
        return json.Unmarshal([]byte(tv), &c) // can't remember the specifics, but this may be needed
    }
    return errors.New("unsupported type")
}

That should handle the stmt.Scan stuff

huangapple
  • 本文由 发表于 2022年7月21日 17:20:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/73063654.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定