模型定义与约束
2026/1/15大约 4 分钟GORM模型约束
模型定义与约束
一、模型定义
1.1 基本模型
type User struct {
ID uint // 主键
Name string // 字符串字段
Email string // 邮箱
Age int // 整数
Birthday time.Time // 时间
Active bool // 布尔值
}1.2 gorm.Model
GORM 提供了一个预定义的模型结构:
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
// 使用
type User struct {
gorm.Model
Name string
Email string
}1.3 字段标签
type User struct {
ID uint `gorm:"primaryKey"` // 主键
Name string `gorm:"size:100;not null"` // 长度和非空
Email string `gorm:"size:100;uniqueIndex"` // 唯一索引
Age int `gorm:"default:0"` // 默认值
Role string `gorm:"type:varchar(50);default:'user'"` // 类型和默认值
CreatedAt time.Time `gorm:"autoCreateTime"` // 自动创建时间
UpdatedAt time.Time `gorm:"autoUpdateTime"` // 自动更新时间
}二、字段标签详解
2.1 主键
type User struct {
ID uint `gorm:"primaryKey"` // 单主键
UUID string `gorm:"primaryKey;size:36"` // 字符串主键
}
// 复合主键
type UserRole struct {
UserID uint `gorm:"primaryKey"`
RoleID uint `gorm:"primaryKey"`
}2.2 字段类型
type Product struct {
Code string `gorm:"type:varchar(100)"` // 指定类型
Price int64 `gorm:"type:bigint"`
Data []byte `gorm:"type:blob"`
}2.3 字段大小
type User struct {
Name string `gorm:"size:100"` // varchar(100)
Password string `gorm:"size:255"` // varchar(255)
}2.4 默认值
type User struct {
Age int `gorm:"default:18"`
Status string `gorm:"default:'active'"`
Score int `gorm:"default:0"`
}2.5 非空约束
type User struct {
Name string `gorm:"not null"`
Email string `gorm:"not null"`
}2.6 唯一约束
type User struct {
Email string `gorm:"unique"` // 单字段唯一
Username string `gorm:"uniqueIndex"` // 唯一索引
// 复合唯一索引
Code string `gorm:"uniqueIndex:idx_code_name"`
Name string `gorm:"uniqueIndex:idx_code_name"`
}三、索引
3.1 普通索引
type User struct {
Name string `gorm:"index"` // 单字段索引
Email string `gorm:"index:idx_email"` // 命名索引
Age int `gorm:"index:idx_age,sort:desc"` // 降序索引
}3.2 复合索引
type User struct {
Name string `gorm:"index:idx_name_age"`
Age int `gorm:"index:idx_name_age"`
Email string `gorm:"index:idx_email_phone"`
Phone string `gorm:"index:idx_email_phone"`
}3.3 唯一索引
type User struct {
Email string `gorm:"uniqueIndex"`
Phone string `gorm:"uniqueIndex:idx_phone"`
}3.4 索引选项
type User struct {
Name string `gorm:"index:,class:FULLTEXT,option:WITH PARSER ngram"`
Age int `gorm:"index:,where:age > 0"`
}四、字段权限
4.1 只读字段
type User struct {
Name string `gorm:"<-:create"` // 只能创建
Age int `gorm:"<-:update"` // 只能更新
CreatedAt time.Time `gorm:"<-:create"` // 只能创建
}4.2 忽略字段
type User struct {
Name string
Password string `gorm:"-"` // 完全忽略
Token string `gorm:"-:all"` // 所有操作忽略
TempData string `gorm:"-:migration"` // 迁移时忽略
}4.3 字段权限组合
type User struct {
Name string `gorm:"<-:create"` // 只能创建
Age int `gorm:"<-:update"` // 只能更新
Email string `gorm:"<-"` // 可读写
CreatedAt time.Time `gorm:"->"` // 只读
}五、自动时间戳
5.1 创建时间
type User struct {
CreatedAt time.Time `gorm:"autoCreateTime"` // 秒级时间戳
CreatedAt int64 `gorm:"autoCreateTime:nano"` // 纳秒时间戳
CreatedAt int64 `gorm:"autoCreateTime:milli"` // 毫秒时间戳
}5.2 更新时间
type User struct {
UpdatedAt time.Time `gorm:"autoUpdateTime"`
UpdatedAt int64 `gorm:"autoUpdateTime:nano"`
}5.3 完整示例
type User struct {
ID uint `gorm:"primaryKey"`
Name string
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"`
}六、软删除
6.1 使用 DeletedAt
type User struct {
ID uint
Name string
DeletedAt gorm.DeletedAt `gorm:"index"`
}
// 删除(软删除)
db.Delete(&user)
// 查询时自动过滤软删除记录
db.Find(&users)
// 包含软删除记录
db.Unscoped().Find(&users)
// 永久删除
db.Unscoped().Delete(&user)6.2 自定义软删除字段
type User struct {
ID uint
Name string
IsDeleted bool `gorm:"default:false"`
}七、字段序列化
7.1 JSON 标签
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"size:100" json:"name"`
Email string `gorm:"size:100" json:"email"`
Password string `gorm:"size:255" json:"-"` // 不序列化
CreatedAt time.Time `json:"created_at"`
}7.2 自定义序列化
type User struct {
ID uint
Name string
Tags datatypes.JSON `gorm:"type:json"`
}
// 使用
user := User{
Name: "张三",
Tags: datatypes.JSON([]byte(`{"role":"admin","level":5}`)),
}八、嵌入结构体
8.1 匿名嵌入
type Author struct {
Name string
Email string
}
type Blog struct {
ID uint
Title string
Author Author `gorm:"embedded"`
}
// 生成的字段: id, title, name, email8.2 带前缀嵌入
type Blog struct {
ID uint
Title string
Author Author `gorm:"embedded;embeddedPrefix:author_"`
}
// 生成的字段: id, title, author_name, author_email九、完整示例
9.1 用户模型
package models
import (
"gorm.io/gorm"
"time"
)
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Username string `gorm:"size:50;not null;uniqueIndex" json:"username"`
Email string `gorm:"size:100;not null;uniqueIndex" json:"email"`
Password string `gorm:"size:255;not null" json:"-"`
Nickname string `gorm:"size:50" json:"nickname"`
Avatar string `gorm:"size:255" json:"avatar"`
Phone string `gorm:"size:20;index" json:"phone"`
Status int `gorm:"default:1;comment:状态 1正常 0禁用" json:"status"`
LastLogin *time.Time `json:"last_login"`
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
func (User) TableName() string {
return "users"
}9.2 文章模型
type Article struct {
ID uint `gorm:"primaryKey" json:"id"`
Title string `gorm:"size:200;not null;index" json:"title"`
Content string `gorm:"type:text" json:"content"`
AuthorID uint `gorm:"not null;index" json:"author_id"`
CategoryID uint `gorm:"index" json:"category_id"`
Tags string `gorm:"size:255" json:"tags"`
ViewCount int `gorm:"default:0" json:"view_count"`
LikeCount int `gorm:"default:0" json:"like_count"`
Status int `gorm:"default:0;comment:0草稿 1发布" json:"status"`
PublishedAt *time.Time `json:"published_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}