为了账号安全,请及时绑定邮箱和手机立即绑定

Golang:将 json 字符串从 mysql db 解码为 struct

Golang:将 json 字符串从 mysql db 解码为 struct

Go
沧海一幻觉 2021-11-15 16:58:17
我试图从我的数据库中获取信息,我的一个字段实际上是作为字符串存储的 JSON,我想将它作为一个结构来获取。这是我行的结构://there is json flag because I use it to get data from redis tootype InfoClip struct { ClipId             string `json:clipId` StreamUrl          string `json:streamUrl` StartTimeCode      int `json:startTimeCode` EndTimeCode        int `json:endTimeCode` CreatedAt          string `json:createdAt` Metas              string `json:metas` // here I get a string instead of a 'metas' struct SourceId           string `json:sourceId` ProviderName       string `json:providerName` ProviderReference  string `json:providerReference` PublicationStatus  string `json:publicationStatus` UserId             string `json:userId` Name               string `json:name` FacebookPage       string `json:facebookPage` TwitterHandle      string `json:twitterHandle` PermaLinkUrl       string `json:permalinkUrl` Logo               string `json:logo` Link               string `json:link`}这是我的metas结构:type metas struct { Title      string `json:title` Tags       []string `json:tags` categories []string `json:permalink`}这就是我试图获得这个领域的方式func decodeJsonSql (met string) (*metas, error) { m := metas{} if err := json.Unmarshal([]byte(met), &m); err != nil {    fmt.Printf("Error decode metas: ", err)    return nil, err } else {    return &m, err } } func CheckIdSql(mediaId string) (error){ datab, err := sql.Open("mysql", "tcp()") if err != nil {    fmt.Printf("[SQL ERROR] Cannot Open db => ", err)    return err}if err := datab.Ping(); err != nil {    fmt.Printf("[SQL ERROR] db connection => ", err)    return err}fmt.Printf("[SQL ONLINE] =>", datab)defer datab.Close()q := "SELECT c.id AS clipId, c.streamUrl, c.startTimecode,  c.endTimecode, c.createdAt, s.metas,... FROM clips WHERE c.id = ?"rows, err := datab.Query(q, mediaId)if err != nil || err == sql.ErrNoRows {    fmt.Printf("SQL Err: %s", err)    return err}但是这个过程相当繁重,肯定有更简单的方法吗?谢谢。
查看完整描述

1 回答

?
浮云间

TA贡献1829条经验 获得超4个赞

你可以让你的metas结构实现sql.Scanner接口


它应该是这样的:


func (m *metas) Scan(src interface{}) error {

    strValue, ok := src.(string)


    if !ok {

        return fmt.Errorf("metas field must be a string, got %T instead", src)

    }


    return json.Unmarshal([]byte(strValue), m)

}

之后,您可以将其用作InfoClip字段并将其直接传递给Scan并删除decodeJsonSql:


type InfoClip struct {

    // [...]

    Metas metas `json:metas`

    // [...]

}


q := "SELECT c.id AS clipId, c.streamUrl, c.startTimecode,  c.endTimecode, c.createdAt, s.metas,... FROM clips WHERE c.id = ?"

row := datab.QueryRow(q, mediaId)

clips := InfoClip{}

err := row.Scan(&clips.ClipId, &clips.StreamUrl, &clips.StartTimeCode, &clips.EndTimeCode, &clips.CreatedAt, &clips.Metas) // [...]

if err != nil {

    fmt.Printf("SQL Err: %s", err)

    return err

}

(顺便说一句,你可以看到,我换成datab.Query与datab.QueryRow你期待只有一个结果)


查看完整回答
反对 回复 2021-11-15
  • 1 回答
  • 0 关注
  • 203 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信