How can I work with SQL NULL values and JSON in a good way?

前端 未结 2 1516
有刺的猬
有刺的猬 2020-12-05 02:21

Go types like Int64 and String cannot store null values, so I found I could use sql.NullInt64 and sql.NullString for this.

But when I use t

2条回答
  •  猫巷女王i
    2020-12-05 02:41

    Types like sql.NullInt64 do not implement any special handling for JSON marshaling or unmarshaling, so the default rules apply. Since the type is a struct, it gets marshalled as an object with its fields as attributes.

    One way to work around this is to create your own type that implements the json.Marshaller / json.Unmarshaler interfaces. By embedding the sql.NullInt64 type, we get the SQL methods for free. Something like this:

    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
    }
    

    If you use this type in place of sql.NullInt64, it should be encoded as you expect.

    You can test this example here: http://play.golang.org/p/zFESxLcd-c

提交回复
热议问题