在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
表。但这些列是:
- id(整数)
- residueid(int,外键)
- residuecategoryid(int,外键)
我想做一个附加关联,例如:
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
)中插入数据,然后您可以在 residue_residue_categories
连接表中添加关联。
我添加了 debug()
方法来向您显示发送到数据库的 sql 语句,即使您在不附加调试器的情况下运行代码也是如此。
为了勉强关注逻辑,我在程序中硬编码了一些值,但应该很容易调整到您自己的逻辑。
如果这解决了您的问题,请告诉我,谢谢!
以上就是GORM 使用自定义列配置多对多的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!