gpt4 book ai didi

go - 是否有必要实现 Scanner 接口(interface)和 Valuer 接口(interface)

转载 作者:行者123 更新时间:2023-12-01 21:24:01 30 4
gpt4 key购买 nike

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

这种东西:

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

我已经实现了自定义 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 接口(interface),
像这样的东西:
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() 函数)

第二次。
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 为假,因此它被忽略 here

所以,你的问题的答案是肯定的,即使你不需要扫描它,你也必须实现一个 Scan 方法。

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

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com