模型定义
模型定义
模型是标准的struct
,由Go
的基本数据类型、实现了Scanner和Valuer接口的自定义类型及其指针或别名组成
例如:
Go
type User struct {
ID uint
Name string
Email *string
Age uint8
Birthday *time.Time
MemberNumber sql.NullString
ActivatedAt sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
}
WARNING
结构体小写属性
是不会生成字段
的
约定
gorm
默认使用ID
作为主键
命名策略
gorm
采用的命名策略
:
表名
是蛇形复数
字段名
是蛇形单数
例如结构体如下:
Go
type User struct {
ID uint
UserName string
Age int
Email string
}
通过gorm
生成的表结构如下
sql
CREATE TABLE users
(
id bigint UNSIGNED AUTO_INCREMENT
PRIMARY KEY,
user_name longtext NULL,
age bigint NULL,
email longtext NULL
);
如上所示:
- 结构体名称
User
生成的表名为users
- 字段名称都小写,有
驼峰(UserName)
的字段名称被转换为蛇形(user_name)
自定义表/字段名
如果想自定义表名
,可以通过以下方法
- 实现
TableName
方法,这种方法只会修改当前设置的表
Go
type User struct {
ID uint
UserName string
Age int
Email string
}
// TableName 会将 User 的表名重写为 `customUser`
func (User) TableName() string {
return "customUser"
}
- 修改连接数据库时的配置,全局修改,所有表命名规则都会修改
Go
db, err := gorm.Open(mysql.Open(dbUrl), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
// TablePrefix: "lyb_", // 生成的表名前缀,User结构体生成的表名为lyb_users
// SingularTable: true, // 使用单数表名,设置为true后,User结构体生成的表名为user,而不是users
// NoLowerCase: true, // 跳过转换蛇形命名
// NameReplacer: strings.NewReplacer("User", "Cid"), // 名称替换,执行gorm名称替换策略之前,将User替换为Cid
},
})
gorm.Model
GORM
定义了一个gorm.Model
结构体,其包括字段ID
、CreatedAt
、UpdatedAt
、DeletedAt
Go
// gorm.Model 的定义
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
高级选项
嵌套结构体
- 对于
匿名字段
,GORM
会将其字段包含在父结构体
中,例如:
Go
type User struct {
gorm.Model
Name string
}
// 等效于
type User struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Name string
}
- 对于
普通的结构体
,可以使用embedded
标签
Go
type Author struct {
Name string
Email string
}
type Blog struct {
ID int
Author Author `gorm:"embedded"`
Upvotes int32
}
// 等效于
type Blog struct {
ID int64
Name string
Email string
Upvotes int32
}
- 可以使用标签
embeddedPrefix
添加嵌套结构体字段的名称
Go
type Author struct {
Name string
Email string
}
type Blog struct {
ID int
Author Author `gorm:"embedded;embeddedPrefix:author_"`
Upvotes int32
}
// 等同于如下所示
type Blog struct {
ID int64
AuthorName string
AuthorEmail string
Upvotes int32
}
设置时间格式
GORM
约定使用CreatedAt
、UpdatedAt
追踪创建/更新
时间,格式为time.Time(1998-06-16 12:20:57.919)
,如果想用时间戳
表示,可以将类型修改为int
类型,或者使用autoCreateTime
、autoUpdateTime
等标签
例如
Go
type User struct {
CreatedAt time.Time // 在创建时,如果该字段值为零值,则使用当前时间填充
UpdatedAt int // 在创建时该字段值为零值或者在更新时,使用当前时间戳秒数填充
Updated int64 `gorm:"autoUpdateTime:nano"` // 使用时间戳纳秒数填充更新时间
Updated int64 `gorm:"autoUpdateTime:milli"` // 使用时间戳毫秒数填充更新时间
Created int64 `gorm:"autoCreateTime"` // 使用时间戳秒数填充创建时间
}
字段标签
column
:自定义列名
type
:列数据类型
,例如:bool
、int
、uint
、float
、string
、time
、bytes
size
:定义列数据类型的大小
或长度
primaryKey
:将列定义为主键
unique
:将列定义为唯一键
default
:定义列的默认值
not null
:指定列为NOT NULL
,不可为空embedded
:嵌套字段embeddedPrefix
:嵌入字段的列名前缀
comment
:列的注释
-
:忽略这个字段,-
:没有读/写
权限;-:migration
:没有迁移
权限;-:all
:没有读/写/迁移
权限
自动生成表结构
- 使用
AutoMigrate
来实现
TIP
AutoMigrate
的逻辑是只新增
,不删除
,不修改
,但是如果修改了字段大小(size
)会同步修改)
Go
type Teacher struct {
gorm.Model
Name string `gorm:"type:varchar(32)"`
Age uint8
Gender uint8
}
DB.AutoMigrate(&Teacher{})