Golang 使用gorm进行upsert

Golang 使用gorm进行upsert

upsert 是数据库插入操作的扩展,如果某个唯一字段已经存在,则将本次新增插入操作变成更新操作,否则就正常执行插入操作。

从 1.20.x 开始,GORM 为不同的数据库提供兼容的 Upsert 支持(Upsert-On-Conflict

1 简单应用

// 在 `id` 冲突时将列更新为新值
DB.Clauses(clause.OnConflict{
  Columns:   []clause.Column{{Name: "id"}}, // key colume
  // 也可以用 map [ string ] interface {} { "role" : "user" }
  DoUpdates: clause.AssignmentColumns([]string{"name", "age"}), // column needed to be updated
}).Create(&users)

其中新增还是更新根据指定的唯一索引字段确定。
上例中,id为主键,如果新增的记录id相同(不冲突),则不新增只更新name和age字段,否则新增一条users记录。
等同于下列SQL操作:

// SQL Server
MERGE INTO "users" USING *** WHEN NOT MATCHED THEN INSERT *** WHEN MATCHED THEN UPDATE SET "name"="excluded"."name"; 
//  PostgreSQL
INSERT INTO "users" *** ON CONFLICT ("id") DO UPDATE SET "name"="excluded"."name", "age"="excluded"."age";
// MySQL
INSERT INTO `users` *** ON DUPLICATE KEY UPDATE `name`=VALUES(name),`age=VALUES(age); 

1.1 支持用切片upsert多个记录,用map设置默认值

db.Clauses(clause.OnConflict{ 
 // 在 `id` 冲突时将列更新为默认值
  Columns: []clause.Column{{Name: "id" }}, 
  DoUpdates: clause.Assignments(map[string]interface{}{"role" : "user"}), 
}).Create(&users)  // users可以是切边
// MERGE INTO "users" USING *** WHEN NOT MATCHED THEN INSERT *** WHEN MATCHED THEN UPDATE SET ***; SQL Server 
// INSERT INTO `users` *** ON DUPLICATE KEY UPDATE ***; MySQL

在主键id冲突时,更新users中的"role" 为 “user”。

2 自定义索引字段

DB.Clauses(clause.OnConflict{
  Columns:   []clause.Column{{Name: "key1"}, {Name: "key2"}},
  UpdateAll: true,  // 主键冲突时, 更新除主键的所有字段
}).Create(&users)

使用唯一联合索引字段 key1+key2 ,只有这两个字段联合不唯一时才新增,否则更新users表中的所有字段。
Gorm插入的记录是插入还是更新操作,是根据是否存在主键冲突来决定,当出现主键冲突时则进行更新操作(使用 ON DUPLICATE KEY UPDATE 语句后面的参数),否则进行插入操作。
所以Columns必须是唯一索引,主键索引或者其他唯一联合索引都行。

Golang使用MySQL连接池与GORM ORM库可以提高性能和效率。下面是一个简单的示例代码,展示如何使用GORMMySQL连接池: ```go import ( "fmt" "log" "gorm.io/driver/mysql" "gorm.io/gorm" ) func main() { // 配置MySQL连接信息 dsn := "user:password@tcp(127.0.0.1:3306)/database?charset=utf8mb4&parseTime=True&loc=Local" // 使用连接池创建数据库连接 db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { log.Fatal(err) } // 设置连接池的最大空闲连接数和最大打开连接数 sqlDB, err := db.DB() if err != nil { log.Fatal(err) } sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(100) // 使用GORM进行数据库操作 // 这里可以写入你的业务逻辑 // 关闭数据库连接 err = db.Close() if err != nil { log.Fatal(err) } fmt.Println("MySQL连接池示例代码执行完毕") } ``` 在上面的示例中,我们首先配置了MySQL连接信息,包括用户名、密码、主机和端口以及数据库名称。然后使用`gorm.Open`方法打开数据库连接,并通过`db.DB()`方法获取到底层的`*sql.DB`实例,以便设置连接池的最大空闲连接数和最大打开连接数。最后,我们可以使用GORM进行数据库操作。在结束时,记得调用`db.Close()`关闭数据库连接。 请注意,上述示例代码中使用了`gorm.io/gorm`和`gorm.io/driver/mysql`模块,这是GORM的最新版本。在你的代码中,可能需要替换成你当前使用GORM版本的模块路径。 希望对你有帮助!如有更多问题,请随时提问。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值