问题描述: 定义结构体时,成员的类型为time.Time。声明一个该结构体的切片,并用Find去查询。 数据库中的NULL时间,查询出来不是time.Time的零值,而是上一个下标的time.Time值 gorm版本:gorm.io/gorm v1.23.10 mysql版本:8.0.27 测试数据:
创建表sql
CREATE TABLE `testnulltime` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`testint` int DEFAULT NULL,
`teststring` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`testtime` datetime(3) DEFAULT NULL,
`createTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updateTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
INSERT INTO LINJJJ.testnulltime (testint,teststring,testtime,createTime,updateTime) VALUES
(1,'Q','2022-09-29 17:04:37.405','2022-09-29 17:04:37.405','2022-09-29 17:04:48.323'),
(NULL,'W','2022-09-30 17:04:37.405','2022-09-29 17:04:37.405','2022-09-29 17:04:48.323'),
(3,'E',NULL,'2022-09-29 17:04:37.405','2022-09-29 17:10:23.307'),
(NULL,NULL,'2022-10-02 17:04:37.405','2022-09-29 17:10:23.262','2022-09-29 17:10:23.262'),
(NULL,'T',NULL,'2022-09-29 17:10:23.283','2022-09-29 17:10:23.283'),
(6,NULL,NULL,'2022-09-29 17:10:23.293','2022-09-29 17:10:23.293'),
(NULL,NULL,NULL,'2022-09-29 17:11:33.264','2022-09-29 17:11:33.264');
测试代码:
package main
import (
"database/sql"
"fmt"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type Testnulltime struct {
Id uint64 `gorm:"column:id;type:bigint(20) unsigned;primary_key;AUTO_INCREMENT;comment:文件的唯一id" json:"id"`
Testint int `gorm:"column:testint;type:int(11)" json:"testint"`
Teststring string `gorm:"column:teststring;type:varchar(100)" json:"teststring"`
Testtime time.Time `gorm:"column:testtime;type:datetime(3)" json:"testtime"`
CreateTime time.Time `gorm:"column:createTime;type:datetime(3);default:CURRENT_TIMESTAMP;comment:创建时间;NOT NULL" json:"createTime"`
UpdateTime time.Time `gorm:"column:updateTime;type:datetime(3);default:CURRENT_TIMESTAMP;comment:修改时间;NOT NULL" json:"updateTime"`
}
func (m *Testnulltime) TableName() string {
return "testnulltime"
}
func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/linjjj?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
fmt.Println(err)
}
var test []Testnulltime
db.Find(&test)
for i := 0; i < len(test); i++ {
fmt.Printf("id:%d\t", test[i].Id)
fmt.Printf("Testint:%d\t", test[i].Testint)
fmt.Printf("Teststring:%s\t", test[i].Teststring)
fmt.Printf("Testtime:%v\t\n", test[i].Testtime)
}
}
数据库查询结果:
id|testint|teststring|testtime |createTime |updateTime |
--+-------+----------+-----------------------------+-----------------------------+-----------------------------+
8| 1|Q |2022-09-29 17:04:37.405000000|2022-09-29 17:04:37.405000000|2022-09-29 17:04:48.323000000|
9| |W |2022-09-30 17:04:37.405000000|2022-09-29 17:04:37.405000000|2022-09-29 17:04:48.323000000|
10| 3|E | |2022-09-29 17:04:37.405000000|2022-09-29 17:10:23.307000000|
11| | |2022-10-02 17:04:37.405000000|2022-09-29 17:10:23.262000000|2022-09-29 17:10:23.262000000|
12| |T | |2022-09-29 17:10:23.283000000|2022-09-29 17:10:23.283000000|
13| 6| | |2022-09-29 17:10:23.293000000|2022-09-29 17:10:23.293000000|
14| | | |2022-09-29 17:11:33.264000000|2022-09-29 17:11:33.264000000|
预期运行结果:
id:8 Testint:1 Teststring:Q Testtime:2022-09-29 17:04:37.405 +0800 CST
id:9 Testint:0 Teststring:W Testtime:2022-09-30 17:04:37.405 +0800 CST
id:10 Testint:3 Teststring:E Testtime:0001-01-01 00:00:00 +0000 UTC
id:11 Testint:0 Teststring: Testtime:2022-10-02 17:04:37.405 +0800 CST
id:12 Testint:0 Teststring:T Testtime:0001-01-01 00:00:00 +0000 UTC
id:13 Testint:6 Teststring: Testtime:0001-01-01 00:00:00 +0000 UTC
id:14 Testint:0 Teststring: Testtime:0001-01-01 00:00:00 +0000 UTC
实际运行结果:
id:8 Testint:1 Teststring:Q Testtime:2022-09-29 17:04:37.405 +0800 CST
id:9 Testint:0 Teststring:W Testtime:2022-09-30 17:04:37.405 +0800 CST
id:10 Testint:3 Teststring:E Testtime:2022-09-30 17:04:37.405 +0800 CST
id:11 Testint:0 Teststring: Testtime:2022-10-02 17:04:37.405 +0800 CST
id:12 Testint:0 Teststring:T Testtime:2022-10-02 17:04:37.405 +0800 CST
id:13 Testint:6 Teststring: Testtime:2022-10-02 17:04:37.405 +0800 CST
id:14 Testint:0 Teststring: Testtime:2022-10-02 17:04:37.405 +0800 CST
目前我的解决方法:
修改 gorm@v1.23.10\schema\field.go 795行后增加对*data == nil的特殊处理,初始化个time零值
修改前:
switch fieldValue.Elem().Interface().(type) {
case time.Time:
field.Set = func(ctx context.Context, value reflect.Value, v interface{}) error {
switch data := v.(type) {
case **time.Time:
if data != nil && *data != nil {
field.Set(ctx, value, *data)
}
case time.Time:
修改后
switch fieldValue.Elem().Interface().(type) {
case time.Time:
field.Set = func(ctx context.Context, value reflect.Value, v interface{}) error {
switch data := v.(type) {
case **time.Time:
if data != nil && *data != nil {
field.Set(ctx, value, *data)
}
if *data == nil {
*data = &time.Time{}
field.Set(ctx, value, *data)
}
case time.Time:
Comment From: github-actions[bot]
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking ✨