belongs to
会与另一个模型建立了一对一的连接。 这种模型的每一个实例都“属于”另一个模型的一个实例。
例如,您的应用包含 user 和 company,并且每个 user 能且只能被分配给一个 company。下面的类型就表示这种关系。 注意,在
User
对象中,有一个和
Company
一样的
CompanyID
。 默认情况下,
CompanyID
被隐含地用来在
User
和
Company
之间创建一个外键关系, 因此必须包含在
User
结构体中才能填充
Company
内部结构体。
// `User` 属于 `Company`,`CompanyID` 是外键 type User struct { gorm.Model Name string CompanyID int Company Company type Company struct { ID int Name string要定义一个 belongs to 关系,数据库的表中必须存在外键。默认情况下,外键的名字,使用拥有者的类型名称加上表的主键的字段名字
例如,定义一个User实体属于Company实体,那么外键的名字一般使用CompanyID。
GORM同时提供自定义外键名字的方式,如下例所示。
type User struct { gorm.Model Name string CompanyRefer int Company Company `gorm:"foreignKey:CompanyRefer"` // 使用 CompanyRefer 作为外键 type Company struct { ID int Name string对于 belongs to 关系,GORM 通常使用数据库表,主表(拥有者)的主键值作为外键参考。 正如上面的例子,我们使用主表Company中的主键字段ID作为外键的参考值。
如果在Company实体中设置了User实体,那么GORM会自动把Company中的ID属性保存到User的CompanyID属性中。
同样的,您也可以使用标签
references来更改它,例如:type User struct { gorm.Model Name string CompanyID string Company Company `gorm:"references:Code"` // 使用 Code 作为引用 type Company struct { ID int Code string Name stringBelongs to 的 CRUD
GORM允许通过使用
Preload或者Joins来主动加载实体的关联关系,具体内容请参考,预加载(主动加载)你可以通过
OnUpdate,OnDelete配置标签来增加关联关系的级联操作,如下面的例子,通过GORM可以完成用户和公司的级联更新和级联删除操作:type User struct { gorm.Model Name string CompanyID int Company Company `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"` type Company struct { ID int Name stringHas One
has one与另一个模型建立一对一的关联,但它和一对一关系有些许不同。 这种关联表明一个模型的每个实例都包含或拥有另一个模型的一个实例。例如,您的应用包含 user 和 credit card 模型,且每个 user 只能有一张 credit card。
// User 有一张 CreditCard,UserID 是外键 type User struct { gorm.Model CreditCard CreditCard type CreditCard struct { gorm.Model Number string UserID uint对于
has one关系,同样必须存在外键字段。拥有者将把属于它的模型的主键保存到这个字段。这个字段的名称通常由
has one模型的类型加上其主键生成,对于上面的例子,它是UserID。为 user 添加 credit card 时,它会将 user 的
ID保存到自己的UserID字段。如果你想要使用另一个字段来保存该关系,你同样可以使用标签
foreignKey来更改它,例如:type User struct { gorm.Model CreditCard CreditCard `gorm:"foreignKey:UserName"` // 使用 UserName 作为外键 type CreditCard struct { gorm.Model Number string UserName string默认情况下,拥有者实体会将
has one对应模型的主键保存为外键,您也可以修改它,用另一个字段来保存,例如下个这个使用Name来保存的例子。您可以使用标签
references来更改它,例如:type User struct { gorm.Model Name string `gorm:"index"` CreditCard CreditCard `gorm:"foreignkey:UserName;references:name"` type CreditCard struct { gorm.Model Number string UserName stringGORM 为
has one和has many提供了多态关联支持,它会将拥有者实体的表名、主键值都保存到多态类型的字段中。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 db.Create(&Dog{Name: "dog1", Toy: Toy{Name: "toy1"}}) // INSERT INTO `dogs` (`name`) VALUES ("dog1") // INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","dogs")您可以使用标签
polymorphicValue来更改多态类型的值,例如:type Dog struct { ID int Name string Toy Toy `gorm:"polymorphic:Owner;polymorphicValue:master"` type Toy struct { ID int Name string OwnerID int OwnerType string db.Create(&Dog{Name: "dog1", Toy: Toy{Name: "toy1"}}) // INSERT INTO `dogs` (`name`) VALUES ("dog1") // INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","master")Has One 的 CURD
GORM 可以通过
Preload、Joins预加载has one关联的记录,查看 预加载 获取详情自引用 Has One
type User struct { gorm.Model Name string ManagerID *uint Manager *User你可以通过为标签
constraint配置OnUpdate、OnDelete实现外键约束,在使用 GORM 进行迁移时它会被创建,例如:type User struct { gorm.Model CreditCard CreditCard `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"` type CreditCard struct { gorm.Model Number string UserID uint你也可以在删除记录时通过
Select来删除关联的记录,查看 Delete with Select 获取详情Has Many
has many与另一个模型建立了一对多的连接。 不同于has one,拥有者可以有零或多个关联模型。例如,您的应用包含 user 和 credit card 模型,且每个 user 可以有多张 credit card。
// User 有多张 CreditCard,UserID 是外键 type User struct { gorm.Model CreditCards []CreditCard type CreditCard struct { gorm.Model Number string UserID uint要定义
has many关系,同样必须存在外键。 默认的外键名是拥有者的类型名加上其主键字段名例如,要定义一个属于
User的模型,则其外键应该是UserID。此外,想要使用另一个字段作为外键,您可以使用
foreignKey标签自定义它:type User struct { gorm.Model CreditCards []CreditCard `gorm:"foreignKey:UserRefer"` type CreditCard struct { gorm.Model Number string UserRefer uintGORM 通常使用拥有者的主键作为外键的值。 对于上面的例子,它是
User的ID字段。为 user 添加 credit card 时,GORM 会将 user 的
ID字段保存到 credit card 的UserID字段。同样的,您也可以使用标签
references来更改它,例如:type User struct { gorm.Model MemberNumber string CreditCards []CreditCard `gorm:"foreignKey:UserNumber;references:MemberNumber"` type CreditCard struct { gorm.Model Number string UserNumber stringGORM 为
has one和has many提供了多态关联支持,它会将拥有者实体的表名、主键都保存到多态类型的字段中。type Dog struct { ID int Name string Toys []Toy `gorm:"polymorphic:Owner;"` type Toy struct { ID int Name string OwnerID int OwnerType string db.Create(&Dog{Name: "dog1", Toys: []Toy{{Name: "toy1"}, {Name: "toy2"}}}) // INSERT INTO `dogs` (`name`) VALUES ("dog1") // INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","dogs"), ("toy2","1","dogs")您可以使用标签
polymorphicValue来更改多态类型的值,例如:type Dog struct { ID int Name string Toys []Toy `gorm:"polymorphic:Owner;polymorphicValue:master"` type Toy struct { ID int Name string OwnerID int OwnerType string db.Create(&Dog{Name: "dog1", Toys: []Toy{{Name: "toy1"}, {Name: "toy2"}}}) // INSERT INTO `dogs` (`name`) VALUES ("dog1") // INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","master"), ("toy2","1","master")Has Many 的 CURD
GORM 可以通过
Preload预加载 has many 关联的记录,查看 预加载 获取详情自引用 Has Many
type User struct { gorm.Model Name string ManagerID *uint Team []User `gorm:"foreignkey:ManagerID"`你可以通过为标签
constraint配置OnUpdate、OnDelete实现外键约束,在使用 GORM 进行迁移时它会被创建,例如:type User struct { gorm.Model CreditCards []CreditCard `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"` type CreditCard struct { gorm.Model Number string UserID uint你也可以在删除记录时通过
Select来删除 has many 关联的记录,查看 Delete with Select 获取详情Many To Many
Many to Many 会在两个 model 中添加一张连接表。
例如,您的应用包含了 user 和 language,且一个 user 可以说多种 language,多个 user 也可以说一种 language。
// User 拥有并属于多种 language,`user_languages` 是连接表 type User struct { gorm.Model Languages []Language `gorm:"many2many:user_languages;"` type Language struct { gorm.Model Name string当使用 GORM 的
AutoMigrate为User创建表时,GORM 会自动创建连接表// User 拥有并属于多种 language,`user_languages` 是连接表 type User struct { gorm.Model Languages []*Language `gorm:"many2many:user_languages;"` type Language struct { gorm.Model Name string Users []*User `gorm:"many2many:user_languages;"`对于
many2many关系,连接表会同时拥有两个模型的外键,例如:type User struct { gorm.Model Languages []Language `gorm:"many2many:user_languages;"` type Language struct { gorm.Model Name string // 连接表:user_languages // foreign key: user_id, reference: users.id // foreign key: language_id, reference: languages.id若要重写它们,可以使用标签
foreignKey、references、joinforeignKey、joinReferences。当然,您不需要使用全部的标签,你可以仅使用其中的一个重写部分的外键、引用。type User struct { gorm.Model Profiles []Profile `gorm:"many2many:user_profiles;foreignKey:Refer;joinForeignKey:UserReferID;References:UserRefer;joinReferences:ProfileRefer"` Refer uint `gorm:"index:,unique"` type Profile struct { gorm.Model Name string UserRefer uint `gorm:"index:,unique"` // 会创建连接表:user_profiles // foreign key: user_refer_id, reference: users.refer // foreign key: profile_refer, reference: profiles.user_refer注意: 某些数据库只允许在唯一索引字段上创建外键,如果您在迁移时会创建外键,则需要指定
unique index标签。自引用 Many2Many
自引用 many2many 关系
type User struct { gorm.Model Friends []*User `gorm:"many2many:user_friends"` // 会创建连接表:user_friends // foreign key: user_id, reference: users.id // foreign key: friend_id, reference: users.idGORM 可以通过
Preload预加载 has many 关联的记录,查看 预加载 获取详情Many2Many 的 CURD
自定义连接表
连接表可以是一个全功能的模型,支持Soft Delete、钩子、更多的字段,就跟其它模型一样。您可以通过SetupJoinTable指定它,例如:注意: 自定义连接表要求外键是复合主键或复合唯一索引
type Person struct { ID int Name string Addresses []Address `gorm:"many2many:person_addresses;"` type Address struct { ID uint Name string type PersonAddress struct { PersonID int `gorm:"primaryKey"` AddressID int `gorm:"primaryKey"` CreatedAt time.Time DeletedAt gorm.DeletedAt func (PersonAddress) BeforeCreate(db *gorm.DB) error { // ... // 修改 Person 的 Addresses 字段的连接表为 PersonAddress // PersonAddress 必须定义好所需的外键,否则会报错 err := db.SetupJoinTable(&Person{}, "Addresses", &PersonAddress{})你可以通过为标签
constraint配置OnUpdate、OnDelete实现外键约束,在使用 GORM 进行迁移时它会被创建,例如:type User struct { gorm.Model Languages []Language `gorm:"many2many:user_speaks;"` type Language struct { Code string `gorm:"primarykey"` Name string // CREATE TABLE `user_speaks` (`user_id` integer,`language_code` text,PRIMARY KEY (`user_id`,`language_code`),CONSTRAINT `fk_user_speaks_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE,CONSTRAINT `fk_user_speaks_language` FOREIGN KEY (`language_code`) REFERENCES `languages`(`code`) ON DELETE SET NULL ON UPDATE CASCADE);你也可以在删除记录时通过
Select来删除 many2many 关系的记录,查看 Delete with Select 获取详情如果您的模型使用了 复合主键,GORM 会默认启用复合外键。
您也可以覆盖默认的外键、指定多个外键,只需用逗号分隔那些键名,例如:
type Tag struct { ID uint `gorm:"primaryKey"` Locale string `gorm:"primaryKey"` Value string type Blog struct { ID uint `gorm:"primaryKey"` Locale string `gorm:"primaryKey"` Subject string Body string Tags []Tag `gorm:"many2many:blog_tags;"` LocaleTags []Tag `gorm:"many2many:locale_blog_tags;ForeignKey:id,locale;References:id"` SharedTags []Tag `gorm:"many2many:shared_blog_tags;ForeignKey:id;References:id"` // 连接表:blog_tags // foreign key: blog_id, reference: blogs.id // foreign key: blog_locale, reference: blogs.locale // foreign key: tag_id, reference: tags.id // foreign key: tag_locale, reference: tags.locale // 连接表:locale_blog_tags // foreign key: blog_id, reference: blogs.id // foreign key: blog_locale, reference: blogs.locale // foreign key: tag_id, reference: tags.id // 连接表:shared_blog_tags // foreign key: blog_id, reference: blogs.id // foreign key: tag_id, reference: tags.id查看 复合主键 获取详情
自动创建、更新
在创建、更新记录时,GORM 会通过 Upsert 自动保存关联及其引用记录。
user := User{ Name: "jinzhu", BillingAddress: Address{Address1: "Billing Address - Address 1"}, ShippingAddress: Address{Address1: "Shipping Address - Address 1"}, Emails: []Email{ {Email: "[email protected]"}, {Email: "[email protected]"}, Languages: []Language{ {Name: "ZH"}, {Name: "EN"}, db.Create(&user) // BEGIN TRANSACTION; // INSERT INTO "addresses" (address1) VALUES ("Billing Address - Address 1"), ("Shipping Address - Address 1") ON DUPLICATE KEY DO NOTHING; // INSERT INTO "users" (name,billing_address_id,shipping_address_id) VALUES ("jinzhu", 1, 2); // INSERT INTO "emails" (user_id,email) VALUES (111, "[email protected]"), (111, "[email protected]") ON DUPLICATE KEY DO NOTHING; // INSERT INTO "languages" ("name") VALUES ('ZH'), ('EN') ON DUPLICATE KEY DO NOTHING; // INSERT INTO "user_languages" ("user_id","language_id") VALUES (111, 1), (111, 2) ON DUPLICATE KEY DO NOTHING; // COMMIT; db.Save(&user)如果您想要更新关联的数据,您应该使用
FullSaveAssociations模式:db.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&user) // ... // INSERT INTO "addresses" (address1) VALUES ("Billing Address - Address 1"), ("Shipping Address - Address 1") ON DUPLICATE KEY SET address1=VALUES(address1); // INSERT INTO "users" (name,billing_address_id,shipping_address_id) VALUES ("jinzhu", 1, 2); // INSERT INTO "emails" (user_id,email) VALUES (111, "[email protected]"), (111, "[email protected]") ON DUPLICATE KEY SET email=VALUES(email); // ...跳过自动创建、更新
若要在创建、更新时跳过自动保存,您可以使用
Select或Omit,例如:user := User{ Name: "jinzhu", BillingAddress: Address{Address1: "Billing Address - Address 1"}, ShippingAddress: Address{Address1: "Shipping Address - Address 1"}, Emails: []Email{ {Email: "[email protected]"}, {Email: "[email protected]"}, Languages: []Language{ {Name: "ZH"}, {Name: "EN"}, db.Select("Name").Create(&user) // INSERT INTO "users" (name) VALUES ("jinzhu", 1, 2); db.Omit("BillingAddress").Create(&user) // Skip create BillingAddress when creating a user db.Omit(clause.Associations).Create(&user) // Skip all associations when creating a userNOTE: 对于 many2many 关联,GORM 在创建连接表引用之前,会先 upsert 关联。如果你想跳过关联的 upsert,你可以这样做:
db.Omit("Languages.*").Create(&user)下面的代码将跳过创建关联及其引用
db.Omit("Languages").Create(&user)Select/Omit 关联字段
user := User{ Name: "jinzhu", BillingAddress: Address{Address1: "Billing Address - Address 1", Address2: "addr2"}, ShippingAddress: Address{Address1: "Shipping Address - Address 1", Address2: "addr2"}, // 创建 user 及其 BillingAddress、ShippingAddress // 在创建 BillingAddress 时,仅使用其 address1、address2 字段,忽略其它字段 db.Select("BillingAddress.Address1", "BillingAddress.Address2").Create(&user) db.Omit("BillingAddress.Address2", "BillingAddress.CreatedAt").Create(&user)关联模式包含一些在处理关系时有用的方法
// 开始关联模式 var user User db.Model(&user).Association("Languages") // `user` 是源模型,它的主键不能为空 // 关系的字段名是 `Languages` // 如果匹配了上面两个要求,会开始关联模式,否则会返回错误 db.Model(&user).Association("Languages").Error查找所有匹配的关联记录
db.Model(&user).Association("Languages").Find(&languages)查找带条件的关联
codes := []string{"zh-CN", "en-US", "ja-JP"} db.Model(&user).Where("code IN ?", codes).Association("Languages").Find(&languages) db.Model(& user).Where("code IN ?", codes).Order("code desc").Association("Languages").Find(&languages)为
many to many、has many添加新的关联;为has one,belongs to替换当前的关联db.Model(&user).Association("Languages").Append([]Language{languageZH, languageEN}) db.Model(&user).Association("Languages").Append(&Language{Name: "DE"}) db.Model(&user).Association("CreditCard").Append(&CreditCard{Number: "411111111111"})用一个新的关联替换当前的关联
db.Model(&user).Association("Languages").Replace([]Language{languageZH, languageEN}) db.Model(&user).Association("Languages").Replace(Language{Name: "DE"}, languageEN)如果存在,则删除源模型与参数之间的关系,只会删除引用,不会从数据库中删除这些对象。
db.Model(&user).Association("Languages").Delete([]Language{languageZH, languageEN}) db.Model(&user).Association("Languages").Delete(languageZH, languageEN)删除源模型与关联之间的所有引用,但不会删除这些关联
db.Model(&user).Association("Languages").Clear()返回当前关联的计数
db.Model(&user).Association("Languages").Count() // 条件计数 codes := []string{"zh-CN", "en-US", "ja-JP"} db.Model(&user).Where("code IN ?", codes).Association("Languages").Count()批量处理数据
关联模式也支持批量处理,例如:
// 查询所有用户的所有角色 db.Model(&users).Association("Role").Find(&roles) // 从所有 team 中删除 user A db.Model(&users).Association("Team").Delete(&userA) // 获取去重的用户所属 team 数量 db.Model(&users).Association("Team").Count() // 对于批量数据的 `Append`、`Replace`,参数的长度必须与数据的长度相同,否则会返回 error var users = []User{user1, user2, user3} // 例如:现在有三个 user,Append userA 到 user1 的 team,Append userB 到 user2 的 team,Append userA、userB 和 userC 到 user3 的 team db.Model(&users).Association("Team").Append(&userA, &userB, &[]User{userA, userB, userC}) // 重置 user1 team 为 userA,重置 user2 的 team 为 userB,重置 user3 的 team 为 userA、 userB 和 userC db.Model(&users).Association("Team").Replace(&userA, &userB, &[]User{userA, userB, userC})带 Select 的删除
你可以在删除记录时通过
Select来删除具有 has one、has many、many2many 关系的记录,例如:// 删除 user 时,也删除 user 的 account db.Select("Account").Delete(&user) // 删除 user 时,也删除 user 的 Orders、CreditCards 记录 db.Select("Orders", "CreditCards").Delete(&user) // 删除 user 时,也删除用户所有 has one/many、many2many 记录 db.Select(clause.Associations).Delete(&user) // 删除 users 时,也删除每一个 user 的 account db.Select("Account").Delete(&users)NOTE: Associations will only be deleted if the deleting records’s primary key is not zero, GORM will use those primary keys as conditions to delete selected associations
// DOESN'T WORK db.Select("Account").Where("name = ?", "jinzhu").Delete(&User{}) // 会删除所有 name=`jinzhu` 的 user,但这些 user 的 account 不会被删除 db.Select("Account").Where("name = ?", "jinzhu" ).Delete(&User{ID: 1}) // 会删除 name = `jinzhu` 且 id = `1` 的 user,并且 user `1` 的 account 也会被删除 db.Select("Account").Delete(&User{ID: 1}) // 会删除 id = `1` 的 user,并且 user `1` 的 account 也会被删除
标签 描述 foreignKey 指定当前模型的列作为连接表的外键 references 指定引用表的列名,其将被映射为连接表外键 polymorphic 指定多态类型,比如模型名 polymorphicValue 指定多态值、默认表名 many2many 指定连接表表名 joinForeignKey 指定连接表的外键列名,其将被映射到当前表 joinReferences 指定连接表的外键列名,其将被映射到引用表 constraint 关系约束,例如: OnUpdate、OnDeleteGORM 允许在
Preload的其它 SQL 中直接加载关系,例如:type User struct { gorm.Model Username string Orders []Order type Order struct { gorm.Model UserID uint Price float64 // 查找 user 时预加载相关 Order db.Preload("Orders").Find(&users) // SELECT * FROM users; // SELECT * FROM orders WHERE user_id IN (1,2,3,4); db.Preload("Orders").Preload("Profile").Preload("Role").Find(&users) // SELECT * FROM users; // SELECT * FROM orders WHERE user_id IN (1,2,3,4); // has many // SELECT * FROM profiles WHERE user_id IN (1,2,3,4); // has one // SELECT * FROM roles WHERE id IN (4,5,6); // belongs toJoins 预加载
Preload在一个单独查询中加载关联数据。而Join Preload会使用 inner join 加载关联数据,例如:db.Joins("Company").Joins("Manager").Joins("Account").First(&user, 1) db.Joins("Company").Joins("Manager").Joins("Account").First(&user, "users.name = ?", "jinzhu") db.Joins("Company").Joins("Manager").Joins("Account").Find(&users, "users.id IN ?", []int{1,2,3,4,5})带条件的 Join
db.Joins("Company", DB.Where(&Company{Alive: true})).Find(&users) // SELECT `users`.`id`,`users`.`name`,`users`.`age`,`Company`.`id` AS `Company__id`,`Company`.`name` AS `Company__name` FROM `users` LEFT JOIN `companies` AS `Company` ON `users`.`company_id` = `Company`.`id` AND `Company`.`alive` = true;注意
Join Preload适用于一对一的关系,例如:has one,belongs to预加载全部
与创建、更新时使用
Select类似,clause.Associations也可以和Preload一起使用,它可以用来预加载全部关联,例如:type User struct { gorm.Model Name string CompanyID uint Company Company Role Role Orders []Order db.Preload(clause.Associations).Find(&users)db.Preload("Orders.OrderItems.Product").Preload(clause.Associations).Find(&users)带条件的预加载
// 带条件的预加载 Order db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users) // SELECT * FROM users; // SELECT * FROM orders WHERE user_id IN (1,2,3,4) AND state NOT IN ('cancelled'); db.Where("state = ?", "active").Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users) // SELECT * FROM users WHERE state = 'active'; // SELECT * FROM orders WHERE user_id IN (1,2) AND state NOT IN ('cancelled');自定义预加载 SQL
您可以通过
func(db *gorm.DB) *gorm.DB实现自定义预加载 SQL,例如:db.Preload("Orders", func(db *gorm.DB) *gorm.DB { return db.Order("orders.amount DESC") }).Find(&users) // SELECT * FROM users; // SELECT * FROM orders WHERE user_id IN (1,2,3,4) order by orders.amount DESC;嵌套预加载
GORM 支持嵌套预加载,例如:
db.Preload("Orders.OrderItems.Product").Preload("CreditCard").Find(&users) // 自定义预加载 `Orders` 的条件 // 这样,GORM 就不会加载不匹配的 order 记录 db.Preload("Orders", "state = ?", "paid").Preload("Orders.OrderItems").Find(&users) user_topic表里的id,关联topic_image表里的topicID, //用户在发表话题动态的时候,同时发了多张照片, //查询的时候需要从topic_image表查出用户此条动态发布的所有照片。 //是这样子的一对多关系 1.model字段部分(加外键关联外键) type UserTopic struct { ID int64 `gorm:"primary_key" json:"id"` UserID int64 `json:"user_id"` TopicImgURL string 上下文,准备语句模式,DryRun模式 批处理插入,FindIn批处理,查找地图 SQL Builder,Upsert,锁定,优化器/索引/注释提示,NamedArg,使用SQL Expr搜索/更新/创建 可扩展的灵活插件API:数据库解析器(多个数据库,读/写拆分)/ Prometheus… 我们再聊一聊gorm自动迁移数据库:AutoMigrate()当数据库迁移时,若方法中有从表,gorm是会自动将依赖的主表创建出来的,(多对多关系不会)所以迁移表时,只需要将最从表放入,其他主表都会自动创建。同时也可以认证表与表之间的关系我期待中的表关系如下: 但实际是 我辛辛苦苦写了那么多的tag,都没起作用???可都是去介绍手动创建外键:AddForeignKey() (5条消息) gorm标签外键失效_鹿灏楷silves的博客-CSDN博客可能跟我出错的原因并不一致。居然可以创建出来表的关系。得出结 在 设置外键的时候不是只将字段和要关联的外键的结构体对应上就可以了, 还需要写一个关联的字段id 如: type Blog struct { ID uint `gorm:"primary_key"` Title string `gorm:"not null;size:256"` Content string `gorm:"type:text;not null"` ShowContent string `gorm:"not null"` LookNum int `gorm:"defau 1、事务的隔离级别 由低到高依次为Read uncommitted(未授权读取、读未提交)、Read committed(授权读取、读提交)、Repeatable read(可重复读取)、Serializable(序列化),这四个级别可以逐个解决脏读、不可... 官方文档看起来很容易误导,让开发以为一对多的关系就必须要存在外键,但是我们再真实的开发环境下,大多是不会用到数据库中的物理外键的,仅仅只是做一个逻辑关联就够了.官方文档这里说的必须存在外键是我们再model里面必须要指明外键,而不是数据库中一定要有这个外键, 注意: 这种情况我们就不能使用db.AutoMigrate() 来自动创建表了,因为我们再代码中指明外键,如果再使用 db.AutoMi belongs to 关联建立一个和另一个模型的一对一连接,使得模型声明每个实例都「属于」另一个模型的一个实例 。例如,如果你的应用包含了用户和用户资料, 并且每一个用户资料只分配给一个用户 为了定义从属关系, 外键是必须存在的, 默认的外键使用所有者类型名称加上其主键。像上面的例子,为了声明一个模型属于 User,它的外键应该为 UserID。GORM 提供了一个定制外键的方法,例如: 关联外键 对于从属关系, GORM 通常使用所有者的主键作为外键值,在上面的例子中,就是 User 的 ID。当你 gorm约定GORM倾向于约定,而不是配置。默认情况下,GORM使用ID作为主键,使用结构体名的蛇形复数作为表名,字段名的蛇形作为列名,并使用CreatedAt、UpdatedAt字段追踪创建、更新时间蛇形约定可以看到之前我们创建的struct是,而在数据库生成的表名为productsgorm.ModelGORM定义一个gorm.Model结构体,其包括字段ID、CreatedAt、UpdatedAt、DeletedAt可以自定义TAG,如gorm->主键;...... GORM 是一款使用 Go 语言编写的 ORM(对象关系映射)库,它提供了一种简洁、高效、灵活的方式来操作数据库。GORM 支持多种关系型数据库,包括 MySQL、PostgreSQL、SQLite 等,同时也提供了一些高级功能,例如事务、预加载、关联查询等。 type DtProject struct { gorm.Model Name string `json:"name" form:"name" gorm:"column:name;comment:;type:varchar(191);"` type DtProjectWorkerRel struct { gorm.Model ProjectId uint `json:"projectId" gorm:"comment:项目id;unique_inde