自动创建、更新

在创建、更新记录时,GORM 会通过 Upsert 自动保存关联及其引用记录。

  1. user := User{
  2. Name: "jinzhu",
  3. BillingAddress: Address{Address1: "Billing Address - Address 1"},
  4. ShippingAddress: Address{Address1: "Shipping Address - Address 1"},
  5. Emails: []Email{
  6. {Email: "jinzhu@example.com"},
  7. {Email: "jinzhu-2@example.com"},
  8. },
  9. Languages: []Language{
  10. {Name: "ZH"},
  11. {Name: "EN"},
  12. },
  13. }
  14. db.Create(&user)
  15. // BEGIN TRANSACTION;
  16. // INSERT INTO "addresses" (address1) VALUES ("Billing Address - Address 1") ON DUPLICATE KEY DO NOTHING;
  17. // INSERT INTO "addresses" (address1) VALUES ("Shipping Address - Address 1") ON DUPLICATE KEY DO NOTHING;
  18. // INSERT INTO "users" (name,billing_address_id,shipping_address_id) VALUES ("jinzhu", 1, 2);
  19. // INSERT INTO "emails" (user_id,email) VALUES (111, "jinzhu@example.com") ON DUPLICATE KEY DO NOTHING;
  20. // INSERT INTO "emails" (user_id,email) VALUES (111, "jinzhu-2@example.com") ON DUPLICATE KEY DO NOTHING;
  21. // INSERT INTO "languages" ("name") VALUES ('ZH') ON DUPLICATE KEY DO NOTHING;
  22. // INSERT INTO "user_languages" ("user_id","language_id") VALUES (111, 1) ON DUPLICATE KEY DO NOTHING;
  23. // INSERT INTO "languages" ("name") VALUES ('EN') ON DUPLICATE KEY DO NOTHING;
  24. // INSERT INTO user_languages ("user_id","language_id") VALUES (111, 2) ON DUPLICATE KEY DO NOTHING;
  25. // COMMIT;
  26. db.Save(&user)

跳过自动创建、更新

若要在创建、更新时跳过自动保存,您可以使用 SelectOmit,例如:

  1. user := User{
  2. Name: "jinzhu",
  3. BillingAddress: Address{Address1: "Billing Address - Address 1"},
  4. ShippingAddress: Address{Address1: "Shipping Address - Address 1"},
  5. Emails: []Email{
  6. {Email: "jinzhu@example.com"},
  7. {Email: "jinzhu-2@example.com"},
  8. },
  9. Languages: []Language{
  10. {Name: "ZH"},
  11. {Name: "EN"},
  12. },
  13. }
  14. db.Select("Name").Create(&user)
  15. // INSERT INTO "users" (name) VALUES ("jinzhu", 1, 2);
  16. db.Omit("BillingAddress").Create(&user)
  17. // 创建 user 时,跳过自动创建 BillingAddress
  18. db.Omit(clause.Associations).Create(&user)
  19. // 创建 user 时,跳过自动创建所有关联记录

关联模式

关联模式包含一些在处理关系时有用的方法

  1. // 开始关联模式
  2. var user User
  3. db.Model(&user).Association("Languages")
  4. // `user` 是源模型,它的主键不能为空
  5. // 关系的字段名是 `Languages`
  6. // 如果上面两个条件匹配,会开始关联模式,否则会返回错误
  7. db.Model(&user).Association("Languages").Error

查找关联

查找所有匹配的关联记录

  1. db.Model(&user).Association("Languages").Find(&languages)
  2. // 带条件的查找
  3. codes := []string{"zh-CN", "en-US", "ja-JP"}
  4. db.Model(&user).Where("code IN ?", codes).Association("Languages").Find(&languages)

添加关联

many to manyhas many 添加新的关联;为 has one, belongs to 替换当前的关联

  1. db.Model(&user).Association("Languages").Append([]Language{languageZH, languageEN})
  2. db.Model(&user).Association("Languages").Append(Language{Name: "DE"})
  3. db.Model(&user).Association("CreditCard").Append(CreditCard{Number: "411111111111"})

替换关联

用一个新的关联替换当前的关联

  1. db.Model(&user).Association("Languages").Replace([]Language{languageZH, languageEN})
  2. db.Model(&user).Association("Languages").Replace(Language{Name: "DE"}, languageEN)

删除关联

如果存在,则删除源模型与参数之间的关系,只会删除引用,不会从数据库中删除这些对象。

  1. db.Model(&user).Association("Languages").Delete([]Language{languageZH, languageEN})
  2. db.Model(&user).Association("Languages").Delete(languageZH, languageEN)

清空关联

删除源模型与关联之间的所有引用,但不会删除这些关联

  1. db.Model(&user).Association("Languages").Clear()

关联计数

返回当前关联的计数

  1. db.Model(&user).Association("Languages").Count()

批量处理数据

关联模式支持批量处理数据,例如:

  1. // 查询所有用户的所有角色
  2. db.Model(&users).Association("Role").Find(&roles)
  3. // 将 userA 移出所有的 Team
  4. db.Model(&users).Association("Team").Delete(&userA)
  5. // 获取所有 Team 成员的不重复计数
  6. db.Model(&users).Association("Team").Count()
  7. // 对于 `Append`、`Replace` 的批量处理,参数与数据的长度必须相等,否则会返回错误
  8. var users = []User{user1, user2, user3}
  9. // 例如:我们有 3 个 user,将 userA 添加到 user1 的 Team,将 userB 添加到 user2 的 Team,将 userA、userB、userC 添加到 user3 的 Team
  10. db.Model(&users).Association("Team").Append(&userA, &userB, &[]User{userA, userB, userC})
  11. // 将 user1 的 Team 重置为 userA,将 user2的 team 重置为 userB,将 user3 的 team 重置为 userA、userB 和 userC
  12. db.Model(&users).Association("Team").Replace(&userA, &userB, &[]User{userA, userB, userC})

关联标签

标签 描述
foreignKey 指定外键
references 指定引用
polymorphic 指定多态类型
polymorphicValue 指定多态值、默认表名
many2many 指定连接表表名
jointForeignKey 指定连接表的外键
joinReferences 指定连接表的引用外键
constraint 关系约束