sql - Gorm 在多对多插入中添加多个 slice

标签 sql go go-gorm

我是 go 和 gorm 的新手。我正在尝试在一个 SQL 查询中插入多个值。

我编写此查询是为了向用户添加多个对话:

relationUserConversation := make([][]uint, len(users))
    
for i, v := range users {
    relationUserConversation[i] = []uint{conversation.ID, v}
}
    
result = r.db.Debug().Exec(
            "INSERT INTO `user_has_conversations` (`user_has_conversations`.`conversation_id`, `user_has_conversations`.`user_id`) VALUES ?",
            relationUserConversation, // If i do this it works relationUserConversation[0], relationUserConversation[1]
           // The issue is because the query has this value "VALUES ((35,1),(35,2))", but should be to work (35,1),(35,2)
        )

我还尝试将它直接添加到我想做的对话中,但是我在尝试添加多对多关系时遇到了问题,因为我没有创建用户和用户之间的关系它尝试添加用户的对话。

我的对话模型:

type Conversation struct {
    ID       uint    `gorm:"primarykey"`
    Users    []*User `gorm:"many2many:user_has_conversations;"`
    Messages []ConversationMessage
}

如果我可以在一个查询中创建与相关用户的新对话,而不是先创建对话,然后再创建与用户的关系,那就太好了。

最佳答案

下面是使用 Gorm Appends 方法 ( see documentation here ) 在两个(或更多)模型之间创建多对多关联的最小工作示例。希望您可以根据您的用例进行调整。

package main

import (
    "fmt"
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

type User struct {
    gorm.Model
    Name     string
    Conversations []Conversation `gorm:"many2many:user_conversations;"`
}

type Conversation struct {
    gorm.Model
    Name string
    Users []*User `gorm:"many2many:user_conversations;"`
}

func main() {

    db, err := gorm.Open(sqlite.Open("many2many.db"), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    // Migrate the schema
    err = db.AutoMigrate(&User{}, &Conversation{})
    if err != nil {
        fmt.Print(err)
    }

    userOne := User{
        Name: "User One",
    }
    userTwo := User{
        Name: "User Two",
    }
    // Create users
    db.Create(&userOne)
    db.Create(&userTwo)

    conversation := Conversation{
        Name: "Conversation One",
    }
    // Create conversation
    db.Create(&conversation)


    // Append users
    err = db.Model(&conversation).Association("Users").Append([]User{userOne, userTwo})

    if err != nil {
        fmt.Print(err)
    }


    for _, convUser := range conversation.Users {
        fmt.Println("Hello I am in the conversation: " + convUser.Name)
    }

    // Clean up database
    db.Delete(&userOne)
    db.Delete(&userTwo)
    db.Delete(&conversation)
}

查询次数

如果您在 Gorm 上启用 Debug():

err = db.Debug().Model(&conversation).Association("Users").Append([]User{userOne, userTwo})

它显示了这个:

[0.144ms] [rows:2] INSERT INTO `user_conversations`
 (`conversation_id`,`user_id`) VALUES (8,15),(8,16) ON CONFLICT DO NOTHING

Values 部分是正确的(您尝试手动执行的操作)并使用 ORM 实现。

关于sql - Gorm 在多对多插入中添加多个 slice ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66778094/

相关文章:

php - 查询 SQL 获取用户名并返回密码

MySQL 没有在此查询中使用索引

garbage-collection - 垃圾收集和cgo

linux - 从 OpenSSH 客户端删除字符

go - golang 中的通用处理 CRUD 操作

mysql - 乱码 : json of json not work

PHP 网站搜索脚本

go - golang中如何传递变量

go - 在go中优化SQL数据访问

mysql - SQL子查询导致整体查询变慢