mysql - 戈朗 : Decode json string to struct from mysql db

标签 mysql database go

我正在尝试从我的数据库中获取信息,我的字段之一实际上是存储为字符串的 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
}
clips := InfoClip{}
for rows.Next() {
    rows.Scan(&clips.ClipId, &clips.StreamUrl, &clips.StartTimeCode, &clips.EndTimeCode, &clips.CreatedAt, &clips.Metas, ...)
}
ret, err := decodeJsonSql(clips.Metas)
if err != nil{
    return err
}
clips.Metas = ret
fmt.Printf("\n\n[SQL DEBUG RESPONSE]: %v", clips)
return nil
}

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

最佳答案

你可以让你的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,因为您只需要一个结果)

关于mysql - 戈朗 : Decode json string to struct from mysql db,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33176367/

相关文章:

python - MS SQL通过Windows命令从python恢复数据库

c# - 从 SQL 语句中检索元数据(表名)

database - 我能否使用 JDBC 驱动程序将应用程序故障转移到正确的 Oracle 数据库实例(Data Guard,而非 RAC 集群)

go - 在 Go1 之后有什么聪明的方法可以恢复 exp/html 吗?

mysql - (My)SQL 列名解析的规则是什么?

php - 如何在 SQL 中提交引号 (') 符号

mysql - 在hibernate中如何设置各种表对象的状态

go - 给一个变量赋值 "label"类型,或者如何在指针之间进行类型转换

javascript - 如何在 golang 中接收 jsonp 请求

php - 可调整大小的表格区域 PHP