在PHP开发中,数据库操作是不可避免的一部分。而对于数据库操作框架GORM来说,它的灵活性和强大功能一直备受开发者们的青睐。在多对多关系的处理上,GORM提供了自定义列配置的功能,让开发者可以更加精细地控制数据表之间的关联关系。本文将由php小编西瓜为大家详细介绍如何使用GORM的自定义列配置功能来处理多对多关系,希望能帮助到大家。
我有这 2 个模型:
type residue struct { id int name string categories []*residuecategory `gorm:"many2many:residue_residue_categories"` } type residuecategory struct { id int name string residues []*residue `gorm:"many2many:residue_residue_categories"` }
我已经有了 residue_residue_categories
表。但这些列是:
我想做一个附加关联,例如:
db.model(&data).association("categories").append(categoriesdata)
但是 sql 生成的是:
insert into "residue_residue_categories" ("residue_id","residue_category_id") values (49,4) on conflict do nothing
如您所见,插入 sql 中的列名称不正确。
我已经尝试配置其他字段,例如:
categories []*residuecategory `gorm:"many2many:residue_residue_categories;foreignkey:residueid;association_foreignkey:residuecategoryid"`
Residues []*Residue `gorm:"many2many:residue_residue_categories;association_foreignkey:residueId;foreignkey:residueCategoryId"`
但奇怪的是,gorm 在一个简单的 getbyid
中抛出: invalid 外键:residualid
(在追加关系之前)。我如何配置与这些自定义列名称的关系?
我整理了一个小例子来尝试解决您的问题。首先,让我分享代码,然后我将引导您完成代码的所有相关部分。
package main import ( "fmt" "gorm.io/driver/postgres" "gorm.io/gorm" ) type Residue struct { ID int Name string ResidueResidueCategories []*ResidueResidueCategory } type ResidueResidueCategory struct { ID int `gorm:"primaryKey"` ResidueCategoryId int `gorm:"column:residueCategoryId"` ResidueId int `gorm:"column:residueId"` } type ResidueCategory struct { ID int Name string ResidueResidueCategories []*ResidueResidueCategory } func main() { dsn := "host=localhost port=54322 user=postgres password=postgres dbname=postgres sslmode=disable" db, err := gorm.Open(postgres.Open(dsn)) if err != nil { panic(err) } db.AutoMigrate(&Residue{}, &ResidueCategory{}, &ResidueResidueCategory{}) // insert into parent tables db.Create(&Residue{ID: 1, Name: "residue 1"}) db.Create(&ResidueCategory{ID: 1, Name: "category 1"}) // insert into join table db.Debug().Model(&Residue{ID: 1}).Association("ResidueResidueCategories").Append(&ResidueResidueCategory{ResidueCategoryId: 1, ResidueId: 1}) // fetch data var joinTableRecords []ResidueResidueCategory if err := db.Model(&ResidueResidueCategory{}).Find(&joinTableRecords).Error; err != nil { panic(err) } for _, v := range joinTableRecords { fmt.Println(v) } }
现在,让我们仔细看看每个部分。
结构体的定义已经发生了很大的变化。我必须插入连接表的定义并覆盖其列名称。
请注意,我添加定义只是为了完整性,如果您的连接表已存在于数据库中,您可以忽略它。
另一个变化是我如何将数据插入数据库。首先,您必须在父表(residues
和 residue_categories
)中插入数据,然后您可以在 residues
和 residue_categories
)中插入数据,然后您可以在 residue_residue_categories
连接表中添加关联。
我添加了 debug()
方法来向您显示发送到数据库的 sql 语句,即使您在不附加调试器的情况下运行代码也是如此。
为了勉强关注逻辑,我在程序中硬编码了一些值,但应该很容易调整到您自己的逻辑。
如果这解决了您的问题,请告诉我,谢谢!
以上是GORM 使用自定义列配置多对多的详细内容。更多信息请关注PHP中文网其他相关文章!