Gorm自定义数据类型

参考官网 https://gorm.io/zh_CN/docs/data_types.html

现在有个需求是,数据库存了用户解锁的头像数组,每次都要json序列化和反序列化.之前是给Avatar结构体写了两个方法,发现太麻烦了

Scan和Value分别对应读取和存储。同理,可以扩展其他类型,比如时间

方法1-适合复杂的数据类型

package domain

import (
	"database/sql/driver"
	"encoding/json"
	"errors"
)

// AvatarListJSON 自定义int切片类型,用于数据库JSON字段的自动序列化和反序列化
type AvatarListJSON []int

// Scan 实现sql.Scanner接口,从数据库读取JSON数据并转换为AvatarListJSON
func (al *AvatarListJSON) Scan(value interface{}) error {
	bytes, ok := value.([]byte)
	if !ok {
		return errors.New("invalid type for AvatarListJSON")
	}

	if len(bytes) == 0 {
		*al = []int{}
		return nil
	}

	var temp []int
	if err := json.Unmarshal(bytes, &temp); err != nil {
		return err
	}
	*al = AvatarListJSON(temp)
	return nil
}

// Value 实现driver.Valuer接口,将AvatarListJSON转换为JSON字符串存储到数据库
func (al AvatarListJSON) Value() (driver.Value, error) {
	if len(al) == 0 {
		return "[]", nil
	}

	bytes, err := json.Marshal(al)
	if err != nil {
		return nil, err
	}
	return string(bytes), nil
}

// Avatar 头像结构体
type Avatar struct {
	ID     int64          `gorm:"primaryKey" json:"id"`
	UID    int            `gorm:"index" json:"uid"`              // 所属用户
	Avatar AvatarListJSON `gorm:"column:avatar" json:"avatar"`  // 头像id列表,JSON格式存储
}

func (*Avatar) TableName() string {
	return "avatar"
}

方法2-推荐,支持json格式,serializer会自动序列化

type Avatar struct {
	ID     int64 `gorm:"primaryKey" json:"id"`
	UID    int   `gorm:"index" json:"uid"`                                         // 所属用户
	Avatar []int `gorm:"column:avatar;serializer:json;default:'[]'" json:"avatar"` // 头像id列表,JSON格式存储
}
posted @ 2025-09-10 09:48  朝阳1  阅读(8)  评论(0)    收藏  举报