首页 > 解决方案 > 在使用 go sql 时,在每种类型中重写 Scan 和 Value 方法时避免重复代码

问题描述

Golan SQL plus Gorp 期望所有类型都包含附加到类型的 Scan 和 Value 方法,以便将 Rows 读取到结构中。这在我的项目中添加了很多样板代码,即使方法可以通用,因为我正在将 JSON 写入这些列。

type Type1 struct {
 Type2 Type2
 Type3 Type3
 Type4 Type4
}

type Type2 struct { some primitives... }
type Type3 struct { some primitives... }
type Type4 struct { some primitives... }


func (q Type2) Value() (driver.Value, error) {
    return json.Marshal(q)
}

func (q *Type2) Scan(src interface{}) error {
    source, _ := src.([]byte)
    if string(source) == "null" {
        return nil
    }
    return json.Unmarshal(source, q)
}

func (q Type3) Value() (driver.Value, error) {
    return json.Marshal(q)
}

func (q *Type3) Scan(src interface{}) error {
    source, _ := src.([]byte)
    if string(source) == "null" {
        return nil
    }
    return json.Unmarshal(source, q)
}

func (q Type4) Value() (driver.Value, error) {
    return json.Marshal(q)
}

func (q *Type4) Scan(src interface{}) error {
    source, _ := src.([]byte)
    if string(source) == "null" {
        return nil
    }
    return json.Unmarshal(source, q)
}

有没有办法避免为我的每个结构定义所有相同的值和扫描方法?

该表应如下所示:

Table: Type1
-----------------------
ROW   Type2                Type3               Type4
1     {"name": "MyName"}   {"other": "bla"}    {"other": "bla"}

我尝试使用 @danicheeta 推荐的作文:

type Base struct {} 
type Type2 struct { Base, some primitives... }

func (q Base) Value() (driver.Value, error) {
    return json.Marshal(q)
}

func (q *Base) Scan(src interface{}) error {
    source, _ := src.([]byte)
    if string(source) == "null" {
        return nil
    }
    return json.Unmarshal(source, q)
}

但是,如果我对数据库执行插入操作,结果是:

Table: Type1
-----------------------
ROW   Type2                Type3               Type4
1     {}                   {}                  {}

同样,如果我已经在数据库中“手动”插入了​​这个:

Table: Type1
    -----------------------
    ROW   Type2                Type3               Type4
    1     {"name": "MyName"}   {"other": "bla"}    {"other": "bla"}

并尝试做一个select * from Type1我得到的:

Type1: {
   Type2: {}
   Type3: {}
   Type4: {}
}

标签: gogorp

解决方案


这是一个解决方案:

type Base struct {}

type Type2 struct { Base, some primitives... }
type Type3 struct { Base, some primitives... }
type Type4 struct { Base, some primitives... }

func (q Base) Value() (driver.Value, error) {
    return json.Marshal(q)
}

func (q *Base) Scan(src interface{}) error {
    source, _ := src.([]byte)
    if string(source) == "null" {
        return nil
    }
    return json.Unmarshal(source, q)
}

请注意,嵌入在结构中的 Base 之前不应有 var (我的意思是type Type2 struct { b Base, some primitives... }


推荐阅读