Golang中如何使用GORM创建记录并关联到另一张表的新建ID
Golang中如何使用GORM创建记录并关联到另一张表的新建ID 我有以下表结构:
type OldData struct {
Name string
Date time.Time
}
type NewData struct {
gorm.Model
Name string
}
type History struct {
ID uint
Date time.Time
}
那么我遇到的情况类似于这样:
oldData := &OldData{
Name: "Julia",
Date: time.Now(),
}
newData := &NewData{
Name: oldData.Name,
}
history := &History{
Date: oldData.Date,
}
我该如何创建新的 newData 行,同时让 history.ID 与 newData.ID 相同?如何建立一种关系,使得当我删除 newData.ID 行时,history.ID 行也会从历史表中删除?
我正在寻找一种方法来关联存储在两个不同表中的 newData 和 history。
db.Create(newData)
更多关于Golang中如何使用GORM创建记录并关联到另一张表的新建ID的实战教程也可以访问 https://www.itying.com/category-94-b0.html
但这需要两次数据库查询,一次获取 history.ID,另一次创建 newData。我希望(如果可能的话)只进行一次直接查询。
更多关于Golang中如何使用GORM创建记录并关联到另一张表的新建ID的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
NewData 和 History 总是在同一时间创建,我的问题在于创建新记录时如何关联 ID 和日期。两个表拥有相同数量的 ID,你的第二个方案看起来非常接近我正在寻找的解决方案,能请你展示一些代码吗?
您需要在 NewData 结构体中添加 historyID 字段。
检查这行代码
newData := NewData { Bame : "Your Name", HistoryID : history.ID }
type NewData struct {
gorm.Model
Name string
HistoryID uint64
}
解决方案:
type NewData struct {
gorm.Model
Name string
// 使用 ID 作为外键
History History `gorm:"foreignKey:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
}
type History struct {
ID uint
Date time.Time
}
newData := &NewData{
Name: "Julia",
History: History{
Date: time.Now(),
},
}
// 将在 NewData 和 History 表中同时创建具有相同 ID 的两行数据。
db.Create(newData)
我看到一些GORM的说明做了类似这样的事情:
type NewData struct {
gorm.Model
Name string
Date time.Time gorm:"what I do here?"
}
newData := &NewData{
Name: "someName",
// 期望Date存储在另一个表中,而不是NewData表,
// 但使用与NewData相同的ID。
Date: time.Now(),
}
// 因此,当执行此语句时,NewData只有name列,
// 而Date存储在我们关联的另一个表(History结构体)中,
// 问题是我不知道这是如何实现的。
db.Create(&newData)
根据您描述的情况,History 和 NewData 必须拥有相同数量的记录,并且我猜测 Id 字段是自增的,因此很可能出现相同记录序号对应不同 ID 的情况。您可以这样做:
- 将
NewData和History合并到一个表中(我不确定这是否可行,因为我不了解您的全部业务需求)。 - 在
history表中添加一个外键,以建立与NewData表的关系。这样一来,即使它们没有相同的 ID 也没关系,因为您可以确保能从History表访问到NewData表中正确的记录。
以上只是我的一点浅见。
我认为你可以采用以下方法:
- 在历史记录的ID字段上添加此注解
ID uint64 `gorm:"primary_key;auto_increment;not_null"`
你也可以从NewData结构体开始,只需按照上述定义添加ID字段。
- 为历史记录表执行创建操作
history := History { Date : time.Now() }
result := db.Create(&history)
- 现在历史记录已获得最新的ID,因此为你的NewData结构体分配一个ID字段并创建记录
newData := NewData { Bame : “Your Name”, historyID : history.ID }
result := db.Create(&newData)
在Golang中使用GORM实现这种关联,可以通过外键约束和关联模式来完成。以下是具体的实现方案:
// 首先修改History结构体,添加NewData的外键引用
type History struct {
ID uint
Date time.Time
NewDataID uint // 添加外键字段
NewData NewData // 添加关联关系
}
// 创建记录并建立关联
func CreateWithHistory(db *gorm.DB, oldData *OldData) error {
// 开启事务确保数据一致性
return db.Transaction(func(tx *gorm.DB) error {
// 创建newData记录
newData := &NewData{
Name: oldData.Name,
}
if err := tx.Create(newData).Error; err != nil {
return err
}
// 创建history记录,关联newData的ID
history := &History{
Date: oldData.Date,
NewDataID: newData.ID, // 设置外键
}
if err := tx.Create(history).Error; err != nil {
return err
}
return nil
})
}
// 或者使用GORM的关联创建功能
func CreateWithAssociation(db *gorm.DB, oldData *OldData) error {
newData := &NewData{
Name: oldData.Name,
History: &History{ // 直接关联History
Date: oldData.Date,
},
}
return db.Create(newData).Error
}
// 要启用级联删除,需要在NewData结构体中定义关联
type NewData struct {
gorm.Model
Name string
History History `gorm:"constraint:OnDelete:CASCADE;"` // 添加级联删除约束
}
// 删除操作会自动级联删除关联的history记录
func DeleteWithCascade(db *gorm.DB, newDataID uint) error {
return db.Delete(&NewData{}, newDataID).Error
}
// 查询时也可以预加载关联的history
func GetWithHistory(db *gorm.DB, id uint) (*NewData, error) {
var newData NewData
err := db.Preload("History").First(&newData, id).Error
return &newData, err
}
对于自动迁移,GORM会自动创建外键约束:
// 自动迁移表结构
db.AutoMigrate(&OldData{}, &NewData{}, &History{})
// 或者手动指定外键关系
db.SetupJoinTable(&NewData{}, "History", &History{})
这个方案通过外键约束确保了数据完整性,并通过级联删除实现了当删除newData记录时自动删除关联的history记录。

