0%

Go_Gorm支持的数据类型

Go_Gorm支持的数据类型

GORM 支持广泛的 Go 数据类型,并能自动将它们映射到对应的数据库类型。以下是 GORM 支持的主要数据类型及其在常见数据库(如 MySQL)中的映射关系:


基础数据类型

Go 类型 MySQL 类型 说明
bool TINYINT(1) 布尔值,true=1, false=0
int INT 32位整数
int8 TINYINT 8位整数
int16 SMALLINT 16位整数
int32 INT 32位整数
int64 BIGINT 64位整数
uint INT UNSIGNED 无符号32位整数
uint8 TINYINT UNSIGNED 无符号8位整数
uint16 SMALLINT UNSIGNED 无符号16位整数
uint32 INT UNSIGNED 无符号32位整数
uint64 BIGINT UNSIGNED 无符号64位整数
float32 FLOAT 单精度浮点数
float64 DOUBLE 双精度浮点数
string VARCHAR(255) 字符串(默认长度255),可通过标签指定长度
[]byte BLOB/LONGBLOB 二进制数据
time.Time DATETIME/TIMESTAMP 时间类型,默认精度到秒

高级/特殊类型

Go 类型/用法 MySQL 类型 说明
*int / sql.NullInt64 INT NULL 可空整数
*bool / sql.NullBool TINYINT(1) NULL 可空布尔值
*string / sql.NullString VARCHAR(255) NULL 可空字符串
*float64 / sql.NullFloat64 DOUBLE NULL 可空浮点数
*time.Time / sql.NullTime DATETIME NULL 可空时间
gorm.DeletedAt DATETIME NULL 软删除字段
json.RawMessage JSON (MySQL 5.7+) JSON 数据(需要数据库支持)
map[string]interface{} JSON JSON 对象
[]string / []int JSON 数组(序列化为 JSON)
uuid.UUID (github.com/google/uuid) CHAR(36) UUID 类型
decimal.Decimal (github.com/shopspring/decimal) DECIMAL(65,30) 高精度十进制数

自定义类型处理

GORM 支持通过接口实现自定义类型:

type MyCustomType string

// 实现 Valuer 接口 - 定义如何存储到数据库
func (m MyCustomType) Value() (driver.Value, error) {
return strings.ToUpper(string(m)), nil
}

// 实现 Scanner 接口 - 定义如何从数据库读取
func (m *MyCustomType) Scan(value interface{}) error {
if value == nil {
*m = ""
return nil
}
if v, ok := value.([]byte); ok {
*m = MyCustomType(strings.ToLower(string(v)))
return nil
}
return fmt.Errorf("cannot convert %T to MyCustomType", value)
}

type User struct {
ID uint
Role MyCustomType `gorm:"type:VARCHAR(10)"`
}

类型映射控制

可以通过 GORM 标签精确控制数据库类型:

type Product struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"type:VARCHAR(100);not null"`
Price float64 `gorm:"type:DECIMAL(10,2)"`
Description string `gorm:"type:TEXT"`
IsActive bool `gorm:"default:true"`
CreatedAt time.Time `gorm:"type:TIMESTAMP;default:CURRENT_TIMESTAMP"`
Metadata JSON `gorm:"type:JSON"`
}

// 自定义 JSON 类型
type JSON map[string]interface{}

func (j JSON) Value() (driver.Value, error) {
return json.Marshal(j)
}

func (j *JSON) Scan(value interface{}) error {
if value == nil {
return nil
}
b, ok := value.([]byte)
if !ok {
return errors.New("type assertion to []byte failed")
}
return json.Unmarshal(b, &j)
}

枚举类型处理

虽然 Go 没有原生枚举,但可以通过字符串+检查实现:

type User struct {
ID uint
Status string `gorm:"type:ENUM('active', 'inactive', 'pending');default:'pending'"`
}

// 添加检查约束
func (u *User) BeforeSave(tx *gorm.DB) (err error) {
validStatus := map[string]bool{"active": true, "inactive": true, "pending": true}
if !validStatus[u.Status] {
return errors.New("invalid status value")
}
return nil
}

自动类型推断

当使用 AutoMigrate 时,GORM 会根据 Go 类型自动创建合适的数据库列:

db.AutoMigrate(&Product{})
// 会自动创建:
// - VARCHAR(255) for string
// - BIGINT for int64
// - FLOAT for float32
// - DOUBLE for float64
// - TINYINT(1) for bool
// - DATETIME for time.Time

特殊注意事项

  1. 时间类型

    • time.Time 默认映射为 DATETIME
    • 使用 gorm:"type:TIMESTAMP" 可指定为时间戳
    • 使用 gorm:"autoCreateTime" / gorm:"autoUpdateTime" 自动管理时间
  2. JSON 支持

    • MySQL 5.7+ 原生支持 JSON 类型
    • 旧版本可序列化为字符串存储
  3. 默认值

    Active bool `gorm:"default:true"`
  4. 大小限制

    Description string `gorm:"size:5000"` // TEXT 类型
  5. 自定义类型映射

    gorm:"type:MEDIUMTEXT" // 指定为 MEDIUMTEXT

数据库差异

类型 MySQL PostgreSQL SQLite
布尔值 TINYINT(1) BOOLEAN BOOLEAN
大文本 LONGTEXT TEXT TEXT
数组 JSON ARRAY JSON
JSON JSON (5.7+) JSONB JSON
时间 DATETIME TIMESTAMP DATETIME
自增ID AUTO_INCREMENT SERIAL AUTOINCREMENT

建议在模型定义中显式指定类型以确保跨数据库兼容性。