在使用gorm开发时,如果未对时间字段进行处理,结构体内属性类型为time.Time
type TimeTest struct {
Id int `json:"id" gorm:"primaryKey"`
CreateTime time.Time `json:"create_time" grom:"autoCreateTime"`
UpdateTime time.Time `json:"update_time"`
Value string `json:"value"`
}
问题一:读取到的时间往往这样:"2021-06-15T10:14:02.973528+08:00"
,带着时区和毫秒,当不需要时区和毫秒时,如何格式化时间?
问题二:insert一条数据到time_test表时,update_time
字段是不赋值的,那么,插入数据库后就会这样:0001-01-01 00:00:00.000000 +00:00
,系统赋了一个默认值,当不想插入默认值时如何处理?
前提:需要了解GORM的自定义数据类型
官方地址:https://gorm.io/zh_CN/docs/data_types.html
定义一个自定义数据类型
type LocalTime time.Time
虽然该数据类型实际类型为time.Time,但是不具备time.Time的内置方法,需要重写MarshalJSON方法来实现数据解析
func (t *LocalTime) MarshalJSON() ([]byte, error) {
tTime := time.Time(*t)
return []byte(fmt.Sprintf("\"%v\"", tTime.Format("2006-01-02 15:04:05"))), nil
}
注意:go的格式化时间的规定时间字符串必须为
2006-01-02 15:04:05
,这是go的诞生时间,不能更改为其他时间
(这个时间字符串与java的"yyyy-MM-dd HH:mm:ss")同作用
上一步骤就解决了问题一读取数据时将将时间数据格式化,下面通过实现Scanner和Valuer
接口解决问题二
func (t LocalTime) Value() (driver.Value, error) {
var zeroTime time.Time
tlt := time.Time(t)
//判断给定时间是否和默认零时间的时间戳相同
if tlt.UnixNano() == zeroTime.UnixNano() {
return nil, nil
}
return tlt, nil
}
func (t *LocalTime) Scan(v interface{}) error {
if value, ok := v.(time.Time); ok {
*t = LocalTime(value)
return nil
}
return fmt.Errorf("can not convert %v to timestamp", v)
}
最后,在含有时间字段的结构体使用LocalTime替换time.Time即可完成配置Value方法即在存储时调用,将该方法的返回值进行存储,该方法可以实现数据存储前对数据进行相关 *** 作
Scan方法可以实现在数据查询出来之前对数据进行相关 *** 作
type TimeTest struct {
Id int `json:"id" gorm:"primaryKey"`
CreateTime *LocalTime `json:"create_time" grom:"autoCreateTime"`
UpdateTime *LocalTime `json:"update_time"`
Value string `json:"value"`
}
输出结果如下:
{
"id": 80,
"create_time": "2021-07-25 13:31:03",
"update_time": null,
"value": "postgres"
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)