前言
最近在開發項目時遇到了發現一個問題,
gorm雖然可以自動幫你維護 created_at、updated_at、deleted_at這些關鍵時間字段。但是其原理與弊端需要了解一下。
1.使用方法
通過自定義一個localtime的結構,來控制時間的格式
package utils
import (
"time"
//"strconv"
"fmt"
"database/sql/driver"
"strconv"
)
type LocalTime struct {
time.Time
}
func (t LocalTime) MarshalJSON() ([]byte, error) {
//格式化秒
seconds := t.Unix()
return []byte(strconv.FormatInt(seconds, 10)), nil
}
func (t LocalTime) Value() (driver.Value, error) {
var zeroTime time.Time
if t.Time.UnixNano() == zeroTime.UnixNano() {
return nil, nil
}
return t.Time, nil
}
func (t *LocalTime) Scan(v interface{}) error {
value, ok := v.(time.Time)
if ok {
*t = LocalTime{Time: value}
return nil
}
return fmt.Errorf("can not convert %v to timestamp", v)
}
此時dao的字段結構為
type TestDao struct{
Id uint `gorm:"primary_key,AUTO_INCREMENT" json:"id"`
CreatedAt LocalTime `json:"-"`
UpdatedAt LocalTime `json:"update_at"`
DeletedAt *LocalTime `json:"-"`
}
2.實現原理
其實現方式其實是通過在save變更時,通過callback功能,將其定義為當前時間。文章可參考 傳送門
這樣你就可以通過自定義的LocalTime來控制時間格式。
3.弊端與建議
因為在程序運行時,createAt這類字段的類型還是 LocalTime,所以如果你想自己給其復制,是不太容易做到的。
例如,你想在程序運行時改一下其createAt的時間。你做不到! 因為它的類型是LocalTime,而你的時間要么是時間戳,要么是一個字符串,類型不匹配。。。是不是很尷尬???
所以建議這類保留字段還是不要在程序運行時去修改。只用它作為記錄或標識即可。如果真的需要更改時間,還是自己維護字段的內容吧。例如用int存時間戳或string存字符串。然后每次變更時,去修改它的值。
當然也可以將這工作自己封裝成一個callback函數,這樣你就能夠隨意控制這個字段了。可參考上文傳送門中的內容。
所以,想吐槽的是,gorm對時間格式化的這種實現方式,太不人性化了!
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。
您可能感興趣的文章:- golang 使用time包獲取時間戳與日期格式化操作
- django rest framework serializer返回時間自動格式化方法
- go語言中時間戳格式化的方法
- Go中time.RFC3339 時間格式化的實現