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

我试图从我的数据库中获取信息,我的一个字段实际上是作为字符串存储的 JSON,我想将它作为一个结构来获取。


这是我行的结构:


//there is json flag because I use it to get data from redis too

type 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

}


但是这个过程相当繁重,肯定有更简单的方法吗?谢谢。


沧海一幻觉
浏览 204回答 1
1回答

浮云间

你可以让你的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你期待只有一个结果)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go