模型定义
gorm.Model
gorm有默认的模型,包括ID,CreatedAt,UpdatedAt,DeletedAt
// 基本模型的定义type Model struct {ID uint `gorm:"primary_key"`CreatedAt time.TimeUpdatedAt time.TimeDeletedAt *time.Time}
可以将它嵌入到定义的模型中
// 添加字段 `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`type User struct {gorm.ModelName 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 stringAge 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.ModelProfile ProfileProfileID int}type Profile struct {gorm.ModelName string}// SELECT * FROM profiles WHERE id = 111; // 111是user的外键ProfileIDdb.Model(&user).Related(&profile)
指定外键
type Profile struct {gorm.ModelName string}type User struct {gorm.ModelProfile Profile `gorm:"ForeignKey:ProfileRefer"` // 使用ProfileRefer作为外键ProfileRefer int}
指定外键和关联外键
// Profile通过Refer找到关联的Usertype Profile struct {gorm.ModelRefer stringName string}// User通过ProfileID找到关联的Profiletype User struct {gorm.ModelProfile Profile `gorm:"ForeignKey:ProfileID;AssociationForeignKey:Refer"`ProfileID int}
包含一个
// User 包含一个 CreditCard, UserID 为外键type User struct {gorm.ModelCreditCard CreditCard}type CreditCard struct {gorm.ModelUserID uintNumber string}var card CreditCarddb.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.ModelName stringUserRefer uint}type User struct {gorm.ModelProfile Profile `gorm:"ForeignKey:UserRefer"`}
指定外键和关联外键
type Profile struct {gorm.ModelName stringUserID uint}type User struct {gorm.ModelRefer stringProfile Profile `gorm:"ForeignKey:UserID;AssociationForeignKey:Refer"`}
对比属于与包含一个,十分容易混淆
包含多个
// User 包含多个 emails, UserID 为外键type User struct {gorm.ModelEmails []Email}type Email struct {gorm.ModelEmail stringUserID uint}db.Model(&user).Related(&emails)//// SELECT * FROM emails WHERE user_id = 111; // 111 是 user 的主键
指定外键
type Profile struct {gorm.ModelName stringUserRefer uint}type User struct {gorm.ModelProfiles []Profile `gorm:"ForeignKey:UserRefer"`}
指定外键和关联外键
type Profile struct {gorm.ModelName stringUserID uint}type User struct {gorm.ModelRefer stringProfiles []Profile `gorm:"ForeignKey:UserID;AssociationForeignKey:Refer"`}
多对多
// User 包含并属于多个 languages, 使用 `user_languages` 表连接type User struct {gorm.ModelLanguages []Language `gorm:"many2many:user_languages;"`}type Language struct {gorm.ModelName 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 intName stringToy Toy `gorm:"polymorphic:Owner;"`}type Dog struct {Id intName stringToy Toy `gorm:"polymorphic:Owner;"`}type Toy struct {Id intName stringOwnerId intOwnerType string}
多态属性和多对多显式不支持,并且会抛出错误。
关联模式
// 开始关联模式var user Userdb.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()
