字段是模型的基本组成。GORM 支持丰富的数据类型,也允许自定义数据库字段类型。这一章详细介绍各种字段的定义方式。
type User struct {
ID uint // bigint unsigned, 主键
Age int // int
Score int32 // int
Balance int64 // bigint
Followers uint32 // int unsigned
Views uint64 // bigint unsigned
}
type Product struct {
Price float32 // float
Weight float64 // double
}
type User struct {
Name string // varchar(191)
Bio string // longtext
Avatar string // varchar(191)
}
默认 string 映射为 varchar(191)。191 是 MySQL utf8mb4 索引长度限制。
type User struct {
Active bool // tinyint(1)
Verified bool
}
type Event struct {
CreatedAt time.Time // datetime
StartTime time.Time
EndTime time.Time
}
用 type 标签指定数据库类型:
type User struct {
Name string `gorm:"type:varchar(50)"`
Bio string `gorm:"type:text"`
Avatar string `gorm:"type:varchar(255)"`
Settings string `gorm:"type:json"`
}
type Article struct {
Title string `gorm:"type:varchar(200)"` // 指定长度
Content string `gorm:"type:longtext"` // 长文本
Summary string `gorm:"type:text"` // 文本
Tags string `gorm:"type:json"` // JSON
Image []byte `gorm:"type:blob"` // 二进制
}
type User struct {
Name string `gorm:"size:50"` // varchar(50)
Email string `gorm:"size:100"` // varchar(100)
}
浮点数指定精度:
type Product struct {
Price float64 `gorm:"type:decimal(10,2)"` // 10位总长,2位小数
}
type User struct {
Name string // NOT NULL
Email *string // NULL
Phone *string // NULL
}
使用时:
email := "test@example.com"
user := User{
Name: "张三",
Email: &email, // 有值
Phone: nil, // NULL
}
import "database/sql"
type User struct {
Name string
Age sql.NullInt64 // 可为 NULL 的整数
Bio sql.NullString // 可为 NULL 的字符串
Active sql.NullBool // 可为 NULL 的布尔值
}
使用时:
user := User{
Name: "张三",
Age: sql.NullInt64{Int64: 25, Valid: true},
Bio: sql.NullString{String: "", Valid: false}, // NULL
}
指针类型更简洁,sql.NullXxx 可以区分 NULL 和零值。
type User struct {
Name string `gorm:"default:'匿名'"`
Age int `gorm:"default:18"`
Active bool `gorm:"default:true"`
Role string `gorm:"default:'user'"`
}
注意字符串默认值要加引号。
创建记录时,如果字段为零值,会使用默认值:
user := User{Name: "张三"} // Age=0 会用默认值 18
db.Create(&user)
如果想用零值而不是默认值:
user := User{Name: "张三", Age: 0}
db.Omit("Age").Create(&user) // 忽略 Age 字段
type User struct {
Name string `gorm:"not null"`
Email string `gorm:"not null"`
}
插入 NULL 值会报错。
GORM 默认按字段定义顺序创建表列。如果需要指定:
type User struct {
Name string `gorm:"column:name;type:varchar(100)"`
Age int `gorm:"column:age;type:int"`
}
存储复杂结构:
type User struct {
ID uint
Name string
Settings map[string]string `gorm:"type:json"`
Tags []string `gorm:"type:json;serializer:json"`
}
serializer:json 让 GORM 自动序列化和反序列化。
数据库生成的字段:
type Product struct {
ID uint
Name string
Price float64
Qty int
Total float64 `gorm:"->;type:GENERATED ALWAYS AS (price * qty) STORED"`
}
-> 表示只读字段。
type User struct {
Status string `gorm:"type:enum('active','inactive','banned');default:'active'"`
Role string `gorm:"type:enum('admin','user','guest');default:'user'"`
}
或者用 Go 的 iota:
type Status int
const (
StatusActive Status = iota
StatusInactive
StatusBanned
)
type User struct {
Status Status `gorm:"type:tinyint;default:0"`
}
type File struct {
ID uint
Name string
Content []byte `gorm:"type:blob"`
Data []byte `gorm:"type:longblob"`
}
字段定义的关键点:
| 需求 | 方法 |
|---|---|
| 自定义类型 | gorm:"type:varchar(50)" |
| 字段长度 | gorm:"size:50" |
| 允许 NULL | 使用指针类型或 sql.NullXxx |
| 默认值 | gorm:"default:'value'" |
| 非空约束 | gorm:"not null" |
| 忽略字段 | gorm:"-" |
| 只读字段 | gorm:"->" |
| 序列化 | gorm:"serializer:json" |
合理使用字段定义,可以让模型精确映射数据库结构。下一章介绍字段标签的完整用法。