在使用gorm时,往往默认的数据类型不满足我们的要求,需要使用一些自定义数据类型作为字段类型,并需要设置一些默认值,如下面例子。
定义一个Status数据类型和LocalTime数据类型,分别表示状态和时间,并实现Valuer和Scanner接口(不了解的话可以看gorm自定义数据类型官方文档)
说一下我自定义这两个数据类型的目的,想通过定义Status实现枚举,定义LocalTime实现时间的读取格式化
type Status int64
const (
TaskStatusDisabled Status = 0 // 禁用
TaskStatusFailure Status = 1 // 失败
)
func (s Status) Value() (driver.Value, error) {
return int64(s), nil
}
func (s *Status) Scan(value interface{}) error {
v, ok := value.(int64)
if ok {
*s = Status(v)
return nil
}
return errors.New("CustomizeDataTypeError")
}
type LocalTime time.Time
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)
}
//实现时间格式化
func (t *LocalTime) MarshalJSON() ([]byte, error) {
tTime := time.Time(*t)
return []byte(fmt.Sprintf("\"%v\"", tTime.Format("2006-01-02 15:04:05"))), nil
}
在声明模型时使用这个Status和LocalTime,这里省略一些其他字段
type Task struct {
...
Status Status `json:status gorm:"default 0"`
StartTime *LocalTime `json:"start_time" gorm:"notnull"`
...
}
正题来了!!(前面铺垫有点长…) 当我们设置默认值的时候,对于基本数据类型
int、string、bool这些自定义数据类型可以在gorm:"default ##"后面直接设置对应的默认值就可以了,在插入数据时会系统会自动识别,并插入到DB,如上面定义的Status,配置gorm:"default 0"就可以实现
Debug时发现会将0
识别为TaskStatusDisabled
常量
对于一些引用类型就不能直接设置默认值了,比如我想将LocalTime设置默认值
如我们想这么设置
gorm: "default time.Parse('2006-01-02 15:04:05', '2999-12-31 23:59:59')"
或
gorm: "default LocalTime(time.Parse('2006-01-02 15:04:05', '2999-12-31 23:59:59'))"
统统不起作用
解决方案
GORM提供了我们解决方案,钩子
,官方文档链接
官方给出了如下说明
那我们可以通过在BeforeCreate方法中实现调用create方法前设置LocalTime的默认值
func (t *Task) BeforeCreate(tx *gorm.DB) error {
endTime, _ := time.Parse("2006-01-02 15:04:05", "2999-12-31 23:59:59")
et := LocalTime(endTime)
t.EndTime = &et
return nil
}
注意:虽然我没用
tx *gorm.DB
这个参数,但是这个参数也是必须要有的
说道这里,我们就可以发现这个钩子方法不仅仅可以设置默认值这么简单,可以调用tx.Update(),tx.Delete()等等方法,并且这些 *** 作在一个事务内,更可以在这里做自己想做的任何事情。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)