golang-gorm库自定义数据类型

前言

上一篇golang-gorm库不支持[]string类型问题的解决方法,解决了一个gorm库中正确识别复杂结构体类型的问题,这里根据官方文档简单实现两种常见自定义类型的数据。

首先给出gorm官方文档的地址,遇到相关问题,最好的解决方法始终是查看官方文档,并尝试其中的标准解决方案。

[]string类型

定义需要传入数据库的结构体 RateLimitPolicy,其中两种数据类型,在下面分别定义:

type RateLimitPolicy struct {
	AllowedIpRange AllowedIpRange `json:"allowedIpRange,omitempty"`
	AllowedIps     AllowedIps 		`json:"allowedIps,omitempty"`
}

定义了AllowedIps[]string

type AllowedIps []string

此种类型在gorm中不可以直接识别,需要自定义数据类型。

func (a *AllowedIps) Scan(value interface{}) error {
   bytesValue, ok := value.([]byte)
   if !ok {
      return errors.New(fmt.Sprint("Failed to unmarshal GlobalSslVisitedHosts value:", value))
   }
   return json.Unmarshal(bytesValue, a)
}

// Value return json value, implement driver.Valuer interface
func (a AllowedIps) Value() (driver.Value, error) {
   return json.Marshal(a)
}

通过Scan()Value()两个函数完成自定义。

struct{}类型

定义需要传入数据库的结构体 RateLimitPolicy,其中两种数据类型,在下面分别定义:

type RateLimitPolicy struct {
	AllowedIpRange AllowedIpRange `json:"allowedIpRange,omitempty"`
	AllowedIps     AllowedIps 		`json:"allowedIps,omitempty"`
}

定义了AllowedIpRangestruct{}

type AllowedIpRange struct {
	Begin gwtype.String `json:"begin,omitempty"`
	End   gwtype.String `json:"end,omitempty"`
}

此种类型在gorm中不可以直接识别,需要自定义数据类型。

func (ar *AllowedIpRange) Scan(value interface{}) error {
	bytesValue, ok := value.([]byte)
	if !ok {
		return errors.New(fmt.Sprint("Failed to unmarshal GlobalSslVisitedHosts value:", value))
	}
	return json.Unmarshal(bytesValue, ar)
}

// Value return json value, implement driver.Valuer interface
func (ar AllowedIpRange) Value() (driver.Value, error) {
	return json.Marshal(ar)
}

通过Scan()Value()两个函数完成自定义。

附录:官方文档中自定义数据类型

GORM 提供了少量接口,使用户能够为 GORM 定义支持的数据类型,这里以 json 为例

实现自定义数据类型

Scanner / Valuer

自定义的数据类型必须实现 ScannerValuer 接口,以便让 GORM 知道如何将该类型接收、保存到数据库

例如:

type JSON json.RawMessage

// 实现 sql.Scanner 接口,Scan 将 value 扫描至 Jsonb
func (j *JSON) Scan(value interface{}) error {
  bytes, ok := value.([]byte)
  if !ok {
    return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", value))
  }

  result := json.RawMessage{}
  err := json.Unmarshal(bytes, &result)
  *j = JSON(result)
  return err
}

// 实现 driver.Valuer 接口,Value 返回 json value
func (j JSON) Value() (driver.Value, error) {
  if len(j) == 0 {
    return nil, nil
  }
  return json.RawMessage(j).MarshalJSON()
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值