模型定义
gorm.Model
gorm有默认的模型,包括ID
,CreatedAt
,UpdatedAt
,DeletedAt
// 基本模型的定义
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}
可以将它嵌入到定义的模型中
// 添加字段 `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`
type User struct {
gorm.Model
Name string
}
表名
表名是结构体名称的复数形式
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"
}
}
// 全局禁用表名复数
db.SingularTable(true) // 如果设置为true,`User`的默认表名为`user`,使用`TableName`设置的表名不受影响
可以通过DefaultTableNameHandler
对默认表名应用任何规则
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return "prefix_" + defaultTableName;
}
列名与字段
列名是字段名的蛇形小写
type User struct {
ID uint // 列名为 `id`
Name string // 列名为 `name`
Birthday time.Time // 列名为 `birthday`
CreatedAt time.Time // 列名为 `created_at`
}
// 重设列名
type Animal struct {
AnimalId int64 `gorm:"column:beast_id"` // 设置列名为`beast_id`
Birthday time.Time `gorm:"column:day_of_the_beast"` // 设置列名为`day_of_the_beast`
Age int64 `gorm:"column:age_of_the_beast"` // 设置列名为`age_of_the_beast`
}
字段ID为默认主键,可以通过 primary_key
来设置主键
type User struct {
ID uint // 字段`ID`为默认主键
Name string
}
// 使用tag`primary_key`用来设置主键
type Animal struct {
AnimalId int64 `gorm:"primary_key"` // 设置AnimalId为主键
Name string
Age int64
}
时间
- CreatedAt用于存储创建时间
- UpdatedAt用于存储记录的修改时间
- DeletedAt用于存储记录的删除时间,如果记录存在
``go db.Create(&user) // 将会设置
CreatedAt`为当前时间
// 要更改它的值, 你需要使用Update
db.Model(&user).Update(“CreatedAt”, time.Now())
db.Save(&user) // 将会设置UpdatedAt
为当前时间
db.Model(&user).Update(“name”, “jinzhu”) // 将会设置UpdatedAt
为当前时间
> 删除具有`DeletedAt`字段的记录,它不会冲数据库中删除,但只将字段`DeletedAt`设置为当前时间,并在查询时无法找到记录,请参阅[软删除](http://gorm.book.jasperxu.com/crud.html#sd)
<a name="TZm89"></a>
## 关联
<a name="hhfuO"></a>
### 属于
```go
// `User`属于`Profile`, `ProfileID`为外键(默认)
type User struct {
gorm.Model
Profile Profile
ProfileID int
}
type Profile struct {
gorm.Model
Name string
}
// SELECT * FROM profiles WHERE id = 111; // 111是user的外键ProfileID
db.Model(&user).Related(&profile)
指定外键
type Profile struct {
gorm.Model
Name string
}
type User struct {
gorm.Model
Profile Profile `gorm:"ForeignKey:ProfileRefer"` // 使用ProfileRefer作为外键
ProfileRefer int
}
指定外键和关联外键
// Profile通过Refer找到关联的User
type Profile struct {
gorm.Model
Refer string
Name string
}
// User通过ProfileID找到关联的Profile
type User struct {
gorm.Model
Profile Profile `gorm:"ForeignKey:ProfileID;AssociationForeignKey:Refer"`
ProfileID int
}
包含一个
// User 包含一个 CreditCard, UserID 为外键
type User struct {
gorm.Model
CreditCard CreditCard
}
type CreditCard struct {
gorm.Model
UserID uint
Number string
}
var card CreditCard
db.Model(&user).Related(&card, "CreditCard")
//// SELECT * FROM credit_cards WHERE user_id = 123; // 123 is user's primary key
// CreditCard是user的字段名称,这意味着获得user的CreditCard关系并将其填充到变量
// 如果字段名与变量的类型名相同,如上例所示,可以省略,如:
db.Model(&user).Related(&card)
指定外键
type Profile struct {
gorm.Model
Name string
UserRefer uint
}
type User struct {
gorm.Model
Profile Profile `gorm:"ForeignKey:UserRefer"`
}
指定外键和关联外键
type Profile struct {
gorm.Model
Name string
UserID uint
}
type User struct {
gorm.Model
Refer string
Profile Profile `gorm:"ForeignKey:UserID;AssociationForeignKey:Refer"`
}
对比属于与包含一个,十分容易混淆
包含多个
// User 包含多个 emails, UserID 为外键
type User struct {
gorm.Model
Emails []Email
}
type Email struct {
gorm.Model
Email string
UserID uint
}
db.Model(&user).Related(&emails)
//// SELECT * FROM emails WHERE user_id = 111; // 111 是 user 的主键
指定外键
type Profile struct {
gorm.Model
Name string
UserRefer uint
}
type User struct {
gorm.Model
Profiles []Profile `gorm:"ForeignKey:UserRefer"`
}
指定外键和关联外键
type Profile struct {
gorm.Model
Name string
UserID uint
}
type User struct {
gorm.Model
Refer string
Profiles []Profile `gorm:"ForeignKey:UserID;AssociationForeignKey:Refer"`
}
多对多
// User 包含并属于多个 languages, 使用 `user_languages` 表连接
type User struct {
gorm.Model
Languages []Language `gorm:"many2many:user_languages;"`
}
type Language struct {
gorm.Model
Name string
}
db.Model(&user).Related(&languages, "Languages")
//// SELECT * FROM "languages" INNER JOIN "user_languages" ON "user_languages"."language_id" = "languages"."id" WHERE "user_languages"."user_id" = 111
指定外键和关联外键
type CustomizePerson struct {
IdPerson string `gorm:"primary_key:true"`
Accounts []CustomizeAccount `gorm:"many2many:PersonAccount;ForeignKey:IdPerson;AssociationForeignKey:IdAccount"`
}
type CustomizeAccount struct {
IdAccount string `gorm:"primary_key:true"`
Name string
}
多种包含
type Cat struct {
Id int
Name string
Toy Toy `gorm:"polymorphic:Owner;"`
}
type Dog struct {
Id int
Name string
Toy Toy `gorm:"polymorphic:Owner;"`
}
type Toy struct {
Id int
Name string
OwnerId int
OwnerType string
}
多态属性和多对多显式不支持,并且会抛出错误。
关联模式
// 开始关联模式
var user User
db.Model(&user).Association("Languages")
// `user`是源,它需要是一个有效的记录(包含主键)
// `Languages`是关系中源的字段名。
// 如果这些条件不匹配,将返回一个错误,检查它:
// db.Model(&user).Association("Languages").Error
// Query - 查找所有相关关联
db.Model(&user).Association("Languages").Find(&languages)
// Append - 添加新的many2many, has_many关联, 会替换掉当前 has_one, belongs_to关联
db.Model(&user).Association("Languages").Append([]Language{languageZH, languageEN})
db.Model(&user).Association("Languages").Append(Language{Name: "DE"})
// Delete - 删除源和传递的参数之间的关系,不会删除这些参数
db.Model(&user).Association("Languages").Delete([]Language{languageZH, languageEN})
db.Model(&user).Association("Languages").Delete(languageZH, languageEN)
// Replace - 使用新的关联替换当前关联
db.Model(&user).Association("Languages").Replace([]Language{languageZH, languageEN})
db.Model(&user).Association("Languages").Replace(Language{Name: "DE"}, languageEN)
// Count - 返回当前关联的计数
db.Model(&user).Association("Languages").Count()
// Clear - 删除源和当前关联之间的关系,不会删除这些关联
db.Model(&user).Association("Languages").Clear()