文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-02-13 11:27

关注

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

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

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

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

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

以上就是GORM 使用自定义列配置多对多的详细内容,更多请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯