You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用GORM实现关联字段名称不同且无外键的多表JOIN查询

GORM实现关联字段名不同的多表JOIN查询方案

1. 先定义对应表的模型结构体

首先需要匹配四张表的结构定义GORM模型,示例如下:

// Ticket 对应tickets表
type Ticket struct {
    TicketID   uint   `gorm:"primaryKey;column:ticket_id"`
    CreateUser uint   `gorm:"column:create_user"` // 关联users表的user_id字段
    // 其他tickets表字段按需补充
}

// TicketDetail 对应ticket_details表
type TicketDetail struct {
    TicketDetailID uint `gorm:"primaryKey;column:ticket_detail_id"`
    TicketID       uint `gorm:"column:ticket_id"`
    // 其他ticket_details表字段按需补充
}

// User 对应users表
type User struct {
    UserID     uint `gorm:"primaryKey;column:user_id"`
    EmployeeID uint `gorm:"column:employee_id"`
    // 其他users表字段按需补充
}

// Employee 对应employees表
type Employee struct {
    EmployeeID uint `gorm:"primaryKey;column:employee_id"`
    // 其他employees表字段按需补充
}

2. 方案一:手写JOIN条件(适配无外键场景,最灵活)

这种方式完全对齐你给出的原生SQL逻辑,不需要提前配置模型关联,哪怕数据库没有实际外键也可以直接使用:

// 定义接收结果的结构体,也可以根据需求用嵌套结构
type TicketFullInfo struct {
    Ticket
    TicketDetail
    User
    Employee
}

var result TicketFullInfo
err := db.Model(&Ticket{}).
    Select("tickets.*, ticket_details.*, users.*, employees.*").
    Joins("JOIN ticket_details ON tickets.ticket_id = ticket_details.ticket_id").
    Joins("JOIN users ON tickets.create_user = users.user_id").
    Joins("JOIN employees ON users.employee_id = employees.employee_id").
    Where("tickets.ticket_id = ?", 1). // 按需添加筛选条件
    Scan(&result).Error

注意:如果多张表存在同名字段,不要直接查*,需要手动指定别名避免字段覆盖,比如Select("tickets.id as ticket_id, users.name as user_name")


3. 方案二:配置关联后自动生成JOIN条件

如果需要频繁做这类关联查询,可以通过foreignKey和references标签手动指定关联关系,GORM不需要依赖数据库实际外键即可自动生成关联逻辑:
首先给模型补充关联字段:

type Ticket struct {
    TicketID   uint   `gorm:"primaryKey;column:ticket_id"`
    CreateUser uint   `gorm:"column:create_user"`
    // 指定关联规则:当前表的CreateUser字段关联User表的UserID字段
    User User `gorm:"foreignKey:CreateUser;references:UserID"`
    TicketDetail TicketDetail `gorm:"foreignKey:TicketID;references:TicketID"`
}

type User struct {
    UserID     uint `gorm:"primaryKey;column:user_id"`
    EmployeeID uint `gorm:"column:employee_id"`
    // 指定User关联Employee的规则
    Employee Employee `gorm:"foreignKey:EmployeeID;references:EmployeeID"`
}

配置完成后直接调用Joins预加载即可,GORM会自动拼接关联条件:

var result Ticket
err := db.Model(&Ticket{}).
    Joins("TicketDetail").
    Joins("User").
    Joins("User.Employee").
    Where("tickets.ticket_id = ?", 1).
    First(&result).Error

内容的提问来源于stack exchange,提问作者Tezza Fazar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 07:39:01