一、GORM 模型字段标签基础语法
GORM 使用 struct tag 定义字段行为:
Go
type User struct {
FieldName DataType `gorm:"tag1:value1;tag2:value2" json:"field_name"`
}
优先级(从高到低):
-
gorm:"..."主控制标签(数据库行为) -
其他标签(json、form 等)
-
结构体字段名作为默认列名(SnakeCase)
二、字段标签分类与详解(最重要部分)
1. 基本字段标签
(1) column(指定数据库列名)
Go
gorm:"column:user_name"
(2) type(指定数据库字段类型)
Go
gorm:"type:varchar(100)"
(3) primaryKey(主键)
Go
gorm:"primaryKey"
(4) autoIncrement(自增)
与 primaryKey 组合常用。
Go
gorm:"primaryKey;autoIncrement"
(5) unique / uniqueIndex(唯一约束)
Go
gorm:"unique" // 单字段唯一
gorm:"uniqueIndex" // 创建唯一索引
gorm:"uniqueIndex:idx_name" // 复合唯一索引
(6) index(普通索引)
Go
gorm:"index" // 单字段索引
gorm:"index:idx_name" // 指定索引名
gorm:"index:idx_name,priority:1" // 复合索引顺序
(7) size(字符串长度)
Go
gorm:"size:255"
(8) default(默认值)
Go
gorm:"default:0"
gorm:"default:'unknown'"
(9) not null(非空)
Go
gorm:"not null"
(10) <- / ->(字段读写权限)
控制 GORM 是否对该字段进行写入或读取:
Go
gorm:"<-:create" // 仅创建时写入
gorm:"<-:update" // 仅更新时写入
gorm:"<-:false" // 禁止写入
gorm:"->:false" // 查询不读该字段
gorm:"-:" // 读写都禁用
gorm:"-" // 完全忽略该字段
2. 时间相关标签(CreateAt/UpdatedAt)
(1) autoCreateTime(创建自动填充)
Go
gorm:"autoCreateTime"
gorm:"autoCreateTime:milli" // 毫秒
gorm:"autoCreateTime:nano" // 纳秒
(2) autoUpdateTime(更新自动填充)
Go
gorm:"autoUpdateTime"
gorm:"autoUpdateTime:milli"
gorm:"autoUpdateTime:nano"
3. 外键 / 关联关系标签
(1) foreignKey(外键字段)
Go
gorm:"foreignKey:UserID"
(2) references(指定关联的字段)
Go
gorm:"references:ID"
(3) constraint(外键约束)
Go
gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"
(4) many2many(多对多中间表)
Go
gorm:"many2many:user_roles"
(5) polymorphic(多态关联)
Go
gorm:"polymorphic:Owner"
4. Serializer(序列化字段)
适用于 JSON、MsgPack 等类型存储。
(1) 保存为 JSON
Go
gorm:"serializer:json"
示例:
Go
type User struct {
Hobbies []string `gorm:"serializer:json"`
}
5. Embedded / EmbeddedPrefix(嵌入字段)
(1) embedded(字段嵌入,不创建嵌套)
Go
gorm:"embedded"
(2) embeddedPrefix(嵌入字段添加前缀)
Go
gorm:"embeddedPrefix:user_"
6. comment(字段注释)
Go
gorm:"comment:'用户年龄'"
三、字段标签使用示例(非常完整)
下面是一个实际业务级别的模型,涵盖各种标签。
Go
type User struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:'主键ID'"`
UserName string `gorm:"column:user_name;type:varchar(50);uniqueIndex;not null;comment:'用户名'"`
Email string `gorm:"type:varchar(100);index:idx_email;not null;comment:'邮箱地址'"`
Age int `gorm:"default:0;comment:'年龄'"`
Profile UserProfile `gorm:"embedded;embeddedPrefix:profile_"`
Tags []string `gorm:"serializer:json;comment:'标签(JSON)'"`
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"`
DeletedAt gorm.DeletedAt `gorm:"index"`
}
type UserProfile struct {
Address string `gorm:"type:varchar(200)"`
Avatar string `gorm:"type:varchar(255)"`
}
四、关联模型完整示例
1. 一对多(User 有多个 Orders)
Go
type User struct {
ID uint
Orders []Order `gorm:"foreignKey:UserID"`
}
type Order struct {
ID uint
UserID uint
}
2. 多对多(Users 共享 Roles)
Go
type User struct {
ID uint
Roles []Role `gorm:"many2many:user_roles"`
}
type Role struct {
ID uint
Name string
}
五、GORM 中 Tag 的常见坑和注意事项
1. default 只在建表时生效,不影响运行时零值
如果字段是 0 或 "",GORM 不会主动应用 default。
解决方法:
Go
Age *int `gorm:"default:18"`
2. 字段必须导出(首字母大写)GORM 才能识别
3. 没有 not null 时,GORM 不会自动加默认非空
4. JSON serializer 必须使用 slice 或 map,不支持 struct 直接存储 unless implement Scanner/Valuer
5. uniqueIndex 必须在 AutoMigrate 后才能生效
六、总结表:最常用的 GORM Tag 清单
| 标签 | 作用 |
|---|---|
| column | 指定列名 |
| type | 指定数据库类型 |
| primaryKey | 主键 |
| autoIncrement | 自增 |
| unique / uniqueIndex | 唯一约束 |
| index | 索引 |
| size | 字符串长度 |
| default | 默认值 |
| not null | 非空 |
| <- | 写属性 |
| -> | 读属性 |
| - | 忽略字段 |
| autoCreateTime | 创建时间 |
| autoUpdateTime | 更新时间 |
| foreignKey | 外键字段 |
| references | 外键关联字段 |
| many2many | 多对多 |
| serializer:json | JSON 存储 |
| embedded | 内嵌字段 |
| embeddedPrefix | 内嵌字段前缀 |
| comment | 字段注释 |