模型
模型的概念
在使用GORM时,通常我们需要在代码中定义模型(Models)与数据库中的数据表进行映射,在GORM中模型(Models)通常是正常定义的结构体(模型是标准的 struct,由 Go 的基本数据类型、实现了 Scanner 和 Valuer 接口的自定义类型及其指针或别名组成)。总之意思就是前面一篇概述中用的结构体,在GORM中就称之为模型,模型是与数据表进行映射的结构体。
例如这个UserInfo 结构体,就是我们完全自定义的模型
type UserInfo struct { ID uint Name string Gender string Hobby string }
为了方便模型定义,GORM内置了一个gorm.Model结构体。其包含了4个字段,一个ID作为主键,3个时间相关的字段。一般将这个gorm.Model嵌入我们自定义的结构体中使用
// Model base model definition, including fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`, which could be embedded in your models // type User struct { // gorm.Model // } type Model struct { ID uint `gorm:"primary_key"` CreatedAt time.Time UpdatedAt time.Time DeletedAt *time.Time `sql:"index"` }
将gorm.Model嵌入自定义的模型中
// UserInfo 用户信息 type UserInfo struct { Name string Gender string Hobby string }
模型的定义
更多的字段标签相关的,之间看官方文档即可字段标签
type User struct { gorm.Model //内嵌gorm.Model Name string Age sql.NullInt64 //类型零值 Birthday *time.Time Email string `gorm:"type:varchar(100);unique_index"` //变长类型,最长255,创建唯一索引 Role string `gorm:"size:255"` // 设置字段大小为255 MemberNumber *string `gorm:"unique;not null"` // 设置会员号(member number)唯一并且不为空 Num int `gorm:"AUTO_INCREMENT"` // 设置 num 为自增类型 Address string `gorm:"index:addr"` // 给address字段创建名为addr的索引 IgnoreMe int `gorm:"-"` // 忽略本字段 }
约定
主键的约定
GORM 默认会使用名为ID的字段作为表的主键。
type User struct { ID string // 名为`ID`的字段会默认作为表的主键 Name string } // 通过tag设置,使用`Name`作为主键 type User struct { ID int64 Name string `gorm:"primary_key"` }
表名的约定
表名默认:将驼峰的结构体名称用_下划线分隔,并在末尾增加复数s
//UserInfo -> user_infos type User struct {} // 默认表名是 `users` // 将 User 的表名设置为 `profiles` func (User) TableName() string { return "profiles" } func (u User) TableName() string { if u.Role == "admin" { return "admin_users" } else { return "users" } } // 禁用默认表名的复数形式,如果置为 true,则 `User` 的默认表名是 `user`,没有s db.SingularTable(true)
可以通过Table()指定表名
type User struct {} // 默认表名是 `users` // 使用User结构体创建名为`my_users`的表 db.Table("my_users").CreateTable(&User{}) var my_users []User // SELECT * FROM deleted_users; db.Table("my_users").Find(&deleted_users) // DELETE FROM my_users WHERE name = 'wxf'; db.Table("my_users").Where("name = ?", "wxf").Delete()
GORM还支持更改默认表名称规则:
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string { return "prefix_" + defaultTableName; }
列名的约定
列名由字段名称进行下划线分割来生成
type User struct { ID uint // column name is `id` Name string // column name is `name` Birthday time.Time // column name is `birthday` CreatedAt time.Time // column name is `created_at` }
可以使用结构体tag指定列名:
type Animal struct { AnimalId int64 `gorm:"column:beast_id"` // set column name to `beast_id` Birthday time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast` Age int64 `gorm:"column:age_of_the_beast"` // set column name to `age_of_the_beast` }
gorm.Model的约定
如果模型有 CreatedAt字段,该字段的值将会是初次创建记录的时间。
db.Create(&user) // `CreatedAt`将会是当前时间 // 可以使用`Update`方法来改变`CreateAt`的值 db.Model(&user).Update("CreatedAt", time.Now())
如果模型有UpdatedAt字段,该字段的值将会是每次更新记录的时间。
db.Save(&user) // `UpdatedAt`将会是当前时间 db.Model(&user).Update("name", "jinzhu") // `UpdatedAt`将会是当前时间
如果模型有DeletedAt字段,调用Delete删除该记录时,将会设置DeletedAt字段为当前时间,而不是直接将记录从数据库中删除,即软删除。