GORM 使用自定义列配置多对多

2024年 2月 13日 32.3k 0

gorm 使用自定义列配置多对多

在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)
}
}

登录后复制

现在,让我们仔细看看每个部分。
结构体的定义已经发生了很大的变化。我必须插入连接表的定义并覆盖其列名称。

请注意,我添加定义只是为了完整性,如果您的连接表已存在于数据库中,您可以忽略它。

另一个变化是我如何将数据插入数据库。首先,您必须在父表(residuesresidue_categories)中插入数据,然后您可以在 residue_residue_categories 连接表中添加关联。
我添加了 debug() 方法来向您显示发送到数据库的 sql 语句,即使您在不附加调试器的情况下运行代码也是如此。

为了勉强关注逻辑,我在程序中硬编码了一些值,但应该很容易调整到您自己的逻辑。
如果这解决了您的问题,请告诉我,谢谢!

以上就是GORM 使用自定义列配置多对多的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论