使用GORM在Golang中实现外键的方法

使用GORM在Golang中实现外键的方法 我有以下两个模型:

用户模型:

type User struct {
    DBBase
    Email    string `gorm:"column:email" json:"email"`
    Password string `gorm:"column:password" json:"-"`
}

func (User) TableName() string {
    return "t_user"
}

用户信息模型:

type UserInfo struct {
    UID       uint   `gorm:"column:u_id" json:"-"`
    FirstName string `gorm:"column:first_name" json:"first_name"`
    LastName  string `gorm:"column:last_name" json:"last_name"`
    Phone     string `gorm:"column:phone" json:"phone"`
    Address   string `gorm:"column:address" json:"address"`
}

func (UserInfo) TableName() string {
    return "t_user_info"
}

我想让UID与用户表的id建立关联。

我尝试了GORM文档中写的方法,但没有成功:http://doc.gorm.io/associations.html


更多关于使用GORM在Golang中实现外键的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于使用GORM在Golang中实现外键的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在GORM中实现外键关联需要正确配置模型之间的关系。根据您的模型结构,以下是实现外键关联的解决方案:

1. 修改模型定义

首先需要修改您的模型,添加GORM的关系标签:

type User struct {
    DBBase
    Email    string    `gorm:"column:email" json:"email"`
    Password string    `gorm:"column:password" json:"-"`
    UserInfo UserInfo  `gorm:"foreignKey:UID"` // 添加一对一关系
}

func (User) TableName() string {
    return "t_user"
}

type UserInfo struct {
    ID        uint   `gorm:"primaryKey;column:id" json:"id"`
    UID       uint   `gorm:"column:u_id;not null" json:"-"`
    FirstName string `gorm:"column:first_name" json:"first_name"`
    LastName  string `gorm:"column:last_name" json:"last_name"`
    Phone     string `gorm:"column:phone" json:"phone"`
    Address   string `gorm:"column:address" json:"address"`
}

func (UserInfo) TableName() string {
    return "t_user_info"
}

2. 自动迁移创建表

使用GORM的自动迁移功能创建带有外键约束的表:

package main

import (
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

func main() {
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    // 自动迁移创建表
    err = db.AutoMigrate(&User{}, &UserInfo{})
    if err != nil {
        panic("failed to migrate database")
    }
}

3. 创建关联数据

创建用户和用户信息的关联数据:

// 创建用户
user := User{
    Email:    "test@example.com",
    Password: "hashed_password",
    UserInfo: UserInfo{
        FirstName: "John",
        LastName:  "Doe",
        Phone:     "1234567890",
        Address:   "123 Main St",
    },
}

// 使用事务创建关联数据
result := db.Create(&user)
if result.Error != nil {
    panic(result.Error)
}

4. 查询关联数据

使用Preload预加载关联的用户信息:

// 查询用户及其关联的用户信息
var user User
result := db.Preload("UserInfo").First(&user, 1)
if result.Error != nil {
    panic(result.Error)
}

// 访问关联的用户信息
fmt.Printf("User: %s, FirstName: %s\n", user.Email, user.UserInfo.FirstName)

5. 使用外键约束

如果需要数据库级别的外键约束,可以在迁移时添加:

// 手动执行SQL添加外键约束
db.Exec(`
    ALTER TABLE t_user_info 
    ADD CONSTRAINT fk_user_info_user 
    FOREIGN KEY (u_id) REFERENCES t_user(id) 
    ON DELETE CASCADE
`)

6. 替代方案:使用References标签

如果上述方法不适用,可以使用References标签明确指定引用字段:

type User struct {
    DBBase
    Email    string    `gorm:"column:email" json:"email"`
    Password string    `gorm:"column:password" json:"-"`
    UserInfo UserInfo  `gorm:"foreignKey:UID;references:ID"`
}

type UserInfo struct {
    ID        uint   `gorm:"primaryKey;column:id" json:"id"`
    UID       uint   `gorm:"column:u_id" json:"-"`
    FirstName string `gorm:"column:first_name" json:"first_name"`
    LastName  string `gorm:"column:last_name" json:"last_name"`
    Phone     string `gorm:"column:phone" json:"phone"`
    Address   string `gorm:"column:address" json:"address"`
}

这些方法可以确保在GORM中正确实现UserInfo的UID字段与User表的ID字段之间的外键关联。

回到顶部