我正在处理要求,其中我收到一个包含日期值作为字符串的JSON对象。我的任务是将Date对象存储在数据库中。

这种东西:

{"start_date": "2019-05-29", "end_date": "2019-08-30"}
{"start_date": "2019-05-29", "end_date": null}

我已经实现了Custom Date类型
type Date struct {
    time.Time
}

我已经实现了UnmarshalJSON接口(interface)
func (d *Date) UnmarshalJSON(b []byte) (err error) {
    if b[0] == '"' && b[len(b)-1] == '"' {
        b = b[1 : len(b)-1]
    }

    // take care of null..
    if len(b) == 0 || string(b) == "null" {
        d.Time = time.Time{}
        return
    }

    d.Time, err = time.Parse("2006-01-02", string(b))
    return
}

还实现了Valuer接口(interface),以将Value返回给sql.Driver。
func (d Date) Value() (driver.Value, error) {
    // check if the date was not set..
    if d.Time.IsZero() {
        return nil, nil
    }
    return d.Time.Format("2006-01-02"), nil
}

但是由于某种原因,直到 Date实现了Scanner界面,
像这样的东西:
func (d Date) Scan(b interface{}) (err error) {
    ...
    return
}

问题:

ORM适配器(GORM)不在数据库中存储记录。有什么线索吗?

完整代码列出here

进一步详细说明

如果我两次运行上面的代码2,我会看到不同的行为,具体取决于是否存在Scan()函数。

1次:
数据库结果
repl_test=# select id, start_date from customer_brokers;
 id | start_date
----+------------
  1 | 2019-05-29


现在都很好..运行相同的代码..(注释了Scan()函数)

第2次。
repl_test=# select id, start_date from customer_brokers;
 id | start_date
----+------------
  1 | 2019-05-29
  2 |             <- start_date empty here..

最佳答案

启用DB.LogMode(true)将显示这两个查询

扫描:

[2019-10-16 14:03:34]  [0.97ms]  INSERT  INTO "custom_brokers" ("created_at","updated_at","deleted_at","start_date","end_date") VALUES ('2019-10-16 14:03:34','2019-10-16 14:03:34',NULL,'2019-05-29',NULL) RETURNING "custom_brokers"."id"

未经扫描:
[2019-10-16 14:02:53]  [0.76ms]  INSERT  INTO "custom_brokers" ("created_at","updated_at","deleted_at") VALUES ('2019-10-16 14:02:53','2019-10-16 14:02:53',NULL) RETURNING "custom_brokers"."id"

第二个显示了gorm完全忽略了模型中的另一列(嵌入式gorm模型除外)

调试之后,我尝试创建模型here,gorm检查该字段是否为sql.Scanner,然后设置IsNormal字段,该字段用于查询创建阶段。如果该字段不是sql.Scanner,则IsNormal为false,因此被忽略here

因此,您问题的答案是肯定的,即使您无需扫描Scan方法也必须实现。

关于go - 是否需要与Valuer接口(interface)一起实现Scanner接口(interface),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58302137/

10-14 17:39
查看更多