2015-10-12 2 views
13

int64のような値を返すと、stringはnull値を格納できません。だから私は がsql.NullInt64とsql.NullStringを使うことができることを知りました。SQLのNULL値とJSONをGolangでうまく処理するにはどうしたらいいですか?

しかし、これらを構造体で使用し、JSONパッケージで構造体からJSONを生成すると、通常のint64とstringを使用したときの形式とは異なります。つまり、sql.Null ***も構造体であるため、追加のレベルがあるということです。

これには適切な回避策がありますか、またはMySQLデータベースにNULLを使用しないでください。

+0

をあなたは、あなたの質問に「私は定期的にInt64型と文字列を使用したときにそれがために使用されていないか」によって何を意味するか説明する必要があります。 – kostya

+1

あなたはintsへのポインタを使用しようとしましたか?つまり:var anint * intを返し、そのポインタがnullの場合は&anintを使用します。 JSONエンコーディングでうまく動作します。これは確かにgorpで動作しますが、まっすぐなSQLパッケージではテストしていません –

答えて

28

sql.NullInt64のようなタイプは、JSONマーシャリングまたはアンマーシャリングの特別な処理を実装しないため、デフォルトのルールが適用されます。型は構造体なので、フィールドを属性として持つオブジェクトとして整列化されます。

これを回避する1つの方法は、json.Marshaller/json.Unmarshalerインターフェイスを実装する独自のタイプを作成することです。 sql.NullInt64型を埋め込むことによって、SQLメソッドが無料で取得されます。このような何か:あなたはsql.NullInt64の代わりにこのタイプを使用する場合は、あなたが期待するよう

type JsonNullInt64 struct { 
    sql.NullInt64 
} 

func (v JsonNullInt64) MarshalJSON() ([]byte, error) { 
    if v.Valid { 
     return json.Marshal(v.Int64) 
    } else { 
     return json.Marshal(nil) 
    } 
} 

func (v *JsonNullInt64) UnmarshalJSON(data []byte) error { 
    // Unmarshalling into a pointer will let us detect null 
    var x *int64 
    if err := json.Unmarshal(data, &x); err != nil { 
     return err 
    } 
    if x != nil { 
     v.Valid = true 
     v.Int64 = *x 
    } else { 
     v.Valid = false 
    } 
    return nil 
} 

、それはエンコードする必要があります。

あなたはここで、この例をテストすることができます。http://play.golang.org/p/zFESxLcd-c

+2

どのような素晴らしいソリューションです!ありがとうございました! – Alex

+6

'null'パッケージは便利なものです。 https://github.com/guregu/null Me likey。 –

+0

Golang Playgroundsにこのようなことを実演してもらうのは冗長かもしれませんが、実際には言語の採用に大きな違いがあります。素晴らしい答えをありがとう。 – NSTJ

関連する問題