栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

gorm设置自定义数据类型字段的默认值

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

gorm设置自定义数据类型字段的默认值

问题背景

在使用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()等等方法,并且这些操作在一个事务内,更可以在这里做自己想做的任何事情。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/903240.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号