写业务过程中,经过会遇到当数据不存在则创建记录,已存在则更新记录的情况,
一开始使用一下代码中的第一种方式,发现没生效,后面改成第二种才生效,在此记录一下。
package main
import (
"log"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type User struct {
ID uint64 `gorm:"primaryKey"`
Email string `gorm:"uniqueIndex"`
Name string
Age int64
}
func main() {
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
if err := db.AutoMigrate(&User{}); err != nil {
log.Fatal(err)
}
user := User{
Email: "demo@qq.com",
Name: "demo",
Age: 20,
}
// 错误写法
if err := createOrUpdate1(db, &user); err != nil {
log.Fatal(err)
}
// 正确写法
if err := createOrUpdate2(db, &user); err != nil {
log.Fatal(err)
}
}
// 错误写法
func createOrUpdate1(db *gorm.DB, user *User) error {
result := db.Where("email = ?", user.Email).FirstOrCreate(&user)
if result.Error != nil {
return result.Error
}
// 此时 user 的字段会更新城数据库里面的值,导致下面语句无效执行
if result.RowsAffected == 0 {
if err := db.Save(&user).Error; err != nil {
return err
}
}
return nil
}
// 正确写法
func createOrUpdate2(db *gorm.DB, user *User) error {
if err := db.Where("email = ?", user.Email).
Assign(User{Name: user.Name, Age: user.Age}).
FirstOrCreate(&user).Error; err != nil {
return err
}
return nil
}