2015-10-16 56 views
0

我想從我的數據庫中獲取信息,而其中一個字段實際上是作爲字符串存儲的JSON,我想將它作爲結構體來存儲。Golang:將json字符串解碼爲來自mysql的結構數據庫db

這是我行的結構:

//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 
} 

但這過程相當沉重,當然有更簡單的方法? 謝謝。

+2

我不明白你的問題是什麼,能否請你更清楚地說明它? –

回答

3

你可以讓你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.Querydatab.QueryRow如您所期望只有一個結果)

+0

感謝您的更正;)我會測試它今晚 – RieuxThomas

+0

我不明白如何實現它,我怎麼能得到這個接口在「row.Next」metas值? – RieuxThomas

+0

@RieuxThomas:用更多的代碼編輯我的答案 – HectorJ

相關問題