Upsert 及冲突(GORM)

GORM支持了数据库的upsert操作

upsert操作对于插入一条数据而言的,如果插入数据之前,没有这条数据,则会插入该条数据;如果插入数据之前就存在这条数据(索引值),就更新这条记录。

创建结构体

type User struct {
	gorm.Model
	Identity string `json:"identity" gorm:"uniqueIndex:idx_identity"`
	Name     string `json:"name"`
	Info     string `json:"info"`
}

代码演示

user := models.User{
		Identity: "zhangsan123",
		Name:     "zhangsan",
		Info:     "zhangsanInfo",
}

res := DB.Clauses(clause.OnConflict{
	Columns: []clause.Column{{Name: "identity"}},
	DoUpdates: clause.Assignments(
		map[string]interface{}{"identity": user.Identity, "name": user.Name, "info": user.Info}),
}).Create(&user).Error
if res != nil {
	log.Printf("UpsertUser Create err:%v\n", res)
} else {
	log.Printf("UpsertUser Create success\n")
}

数据库新增一条数据

在这里插入图片描述

第二次执行

user := models.User{
		Identity: "zhangsan123",
		Name:     "张三",
		Info:     "mine",
}

数据库更新数据

在这里插入图片描述

出现的问题

假设将原来的数据软删除,重新进行修改操作:将名字设置为’李四’,那么是插入一条新的数据还是更新原来数据?
在这里插入图片描述
结果发现是直接更新了已经被GORM软删除的数据
在这里插入图片描述

原因

究其原因是因为在进行upsert语句的时候需要根据唯一索引(Columns字段)进行更新,由于唯一索引的限制,不能实现插入一条新的数据。

如何实现直接插入一条新的数据而不是更新已经删除的数据:将GORM软删除字段加入并成为一个联合索引。
在这里插入图片描述

修改后的结构体

type User struct {
	gorm.Model
	DeletedAt gorm.DeletedAt `json:"-" gorm:"index;uniqueIndex:idx_identity"`
	Identity  string         `json:"identity" gorm:"uniqueIndex:idx_identity"`
	Name      string         `json:"name"`
	Info      string         `json:"info"`
}

代码也要将Columns的条件进行修改

// 定义数据
user := models.User{
	Identity: "zhangsan123",
	Name:     "张三",
	Info:     "mine",
}

res := DB.Clauses(clause.OnConflict{
	//加上联合索引的所有字段
	Columns: []clause.Column{{Name: "identity"}, {Name: "deleted_at"}},
	DoUpdates: clause.Assignments(
		map[string]interface{}{"identity": user.Identity, "name": user.Name, "info": user.Info}),
}).Create(&user).Error
if res != nil {
	log.Printf("UpsertUser Create err:%v\n", res)
} else {
	log.Printf("UpsertUser Create success\n")
}

在这里插入图片描述

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值