GORM查询datetime类型NULL值时被前置有效值覆盖问题求助
GORM查询时time.Time类型字段NULL值被前一个非NULL值覆盖的问题
问题现象
使用GORM查询数据时,实体中Time字段为time.Time类型,数据库中该字段为NULL的记录,查询后会被前一条非NULL的Time值覆盖;将Time字段改为string类型后,查询结果恢复正常。
实体定义(由gen生成)
type Test struct { ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` Time time.Time `gorm:"column:time" json:"time"` }
数据库数据
| ID | time |
|---|---|
| 1 | null |
| 2 | 2022-11-16 16:31:31 |
| 3 | null |
| 4 | null |
查询代码
var tests []entity.Test orm.Find(&tests) fmt.Printf("%+v\n", tests)
预期结果
[ { "id": 1, "time": "0001-01-01T00:00:00Z" }, { "id": 2, "time": "2022-11-16T16:31:31+08:00" }, { "id": 3, "time": "0001-01-01T00:00:00Z" }, { "id": 4, "time": "0001-01-01T00:00:00Z" } ]
实际结果
[ { "id": 1, "time": "0001-01-01T00:00:00Z" }, { "id": 2, "time": "2022-11-16T16:31:31+08:00" }, { "id": 3, "time": "2022-11-16T16:31:31+08:00" }, { "id": 4, "time": "2022-11-16T16:31:31+08:00" } ]
原因分析
time.Time是值类型,GORM在批量查询时会复用结构体实例以提升性能。当某条记录的Time字段为NULL时,GORM不会主动重置该字段的值,导致保留了前一条记录的非NULL值。而string类型的零值是空字符串,GORM会正确处理NULL到空字符串的映射,不会出现值覆盖的情况。
解决方案
推荐采用以下标准方案解决:
将Time字段改为指针类型*time.Time,这样当数据库字段为NULL时,GORM会将其映射为nil,彻底避免值覆盖问题:
type Test struct { ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` Time *time.Time `gorm:"column:time" json:"time"` }
内容的提问来源于stack exchange,提问作者Josefa
相关产品推荐
相关产品推荐

