1. ホーム
  2. go

[解決済み] GORMでレコードを作成・更新するには?

2022-02-10 16:56:24

質問事項

ゴームは FirstOrCreate メソッドと FirstOrInit しかし、レコードが実際に作成されたかどうかを後で確認するにはどうしたらよいでしょうか。私はそれが存在しない場合、レコードを作成し、それが存在する場合、私はいくつかのフィールドを更新したい。

どのように解決するのですか?

アップデート 2020.10.09

謝辞 ヴァイリン

1.20.x以降、GORMは異なるデータベースに対して互換性のあるUpsertサポートを提供します( アップサート・オン・コンフリクト )

// Update columns to new value on `id` conflict
DB.Clauses(clause.OnConflict{
  Columns:   []clause.Column{{Name: "id"}}, // key colume
  DoUpdates: clause.AssignmentColumns([]string{"name", "age"}), // column needed to be updated
}).Create(&users)
// MERGE INTO "users" USING *** WHEN NOT MATCHED THEN INSERT *** WHEN MATCHED THEN UPDATE SET "name"="excluded"."name"; SQL Server
// INSERT INTO "users" *** ON CONFLICT ("id") DO UPDATE SET "name"="excluded"."name", "age"="excluded"."age"; PostgreSQL
// INSERT INTO `users` *** ON DUPLICATE KEY UPDATE `name`=VALUES(name),`age=VALUES(age); MySQL

gorm 1.9.x以下では、最初に更新を行い、存在しないときに挿入するのが効率的です。

// update only set name=nick
if err := db.Model(&newUser).Where("id = ?", 3333).Update("name", "nick").Error; err != nil {
    // always handle error like this, cause errors maybe happened when connection failed or something. 
    // record not found...
    if gorm.IsRecordNotFoundError(err){
        db.Create(&newUser)  // create new record from newUser
    }
}

FirstOrInitFirstOrCreate が異なる場合。データベース内に一致するレコードがない場合。 FirstOrInit は構造体を開始しますが、レコードは作成されません。 FirstOrCreate はレコードを作成し、そのレコードを構造体にクエリします。