• GORM模型更新


    GORM模型更新

    一、更新所有字段

    Save()默认会更新该对象的所有字段,即使你没有赋值。

    package main
    
    import (
    	"fmt"
    	"gorm.io/driver/mysql"
    	"gorm.io/gorm"
    )
    
    type UsersUpdate struct {
    	gorm.Model
    	//Name *string `gorm:"type:varchar(100);default:RandySun;comment:姓名"`
    	Name string `gorm:"type:varchar(100);default:RandySun;comment:姓名"`
    	Age  int64
    	// 设置默认值
    	Active bool
    }
    
    func main() {
    	dsn := "root:@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local"
    	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    	if err != nil {
    		panic(err)
    	}
    	// 迁移表创建对应关系
    	db.AutoMigrate(&UsersUpdate{})
    
    	// 添加数据
    	db.Debug().Create(&UsersUpdate{Name: "bary", Age: 18})
    	db.Debug().Create(&UsersUpdate{Name: "RandySun", Age: 18})
    	db.Debug().Create(&UsersUpdate{Name: "Jack", Age: 18})
    	db.Debug().Create(&UsersUpdate{Name: "", Age: 19}) // 添加记录name默认为Null
    
    	// 查询
    	var user UsersSelect
    	db.Debug().First(&user)
    	fmt.Printf("%#v", user)
        
    	// 更新
    	user.Name = "xiaoSun"
    	user.Age = 18
    	// 保存 save默认更新所有字段
        // UPDATE `users_updates` SET `created_at`='2021-11-23 22:24:20.984',`updated_at`='2021-11-23 22:27:27.243',`deleted_at`=NULL,`name`='xiaoSun',`age`=18,`active`=false WHERE `id` = 1
    	db.Debug().Save(&user)
    
    
    }
    
    

    UPDATEusers_updatesSETcreated_at='2021-11-23 22:24:20.984',updated_at='2021-11-23 22:27:27.243',deleted_at=NULL,name='xiaoSun',age=18,active=false WHERE id = 1

    image-20211123222837794

    image-20211123222813916

    二、更新修改字段

    如果你只希望更新指定字段,可以使用Update或者Updates

    2.1更新指定字段

    // 根据给定的条件更新单个属性
    UPDATE `users_updates` SET `name`='Randy',`updated_at`='2021-11-23 22:52:04.414' WHERE `id` = 1
    db.Debug().Model(&user).Update("name","Randy")
    
    

    image-20211123225215767

    image-20211123225304164

    2.2 条件更新字段

    // 根据给定的条件更新单个属性
    // UPDATE `users_updates` SET `name`='bak',`updated_at`='2021-11-23 22:56:37.193' WHERE active = false AND `users_updates`.`deleted_at` IS NULL AND `id` = 1
    
    db.Debug().Model(&user).Where("active = ?", true).Update("name", "hello")
    

    image-20211123225703195

    image-20211123225723642

    2.3 map 更新多个属性字段

    // 使用 map 更新多个属性,只会更新其中有变化的属性
    //UPDATE `users_updates` SET `active`=true,`age`=119,`name`='',`updated_at`='2021-11-24 08:24:03.114' WHERE `id` = 1
    
    m1 := map[string]interface{}{
        "name":"",
        "age": 119,
        "active": true,
    
    }
    db.Debug().Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false})
    
    

    image-20211124082543045

    image-20211124082525630

    2.4 struct 更新多个属性

    // 使用 struct 更新多个属性,只会更新其中有变化且为非零值的字段
    //  UPDATE `users_updates` SET `updated_at`='2021-11-24 08:28:40.079',`name`='hello' WHERE `id` = 1
    var user UsersUpdate
    db.Debug().First(&user)
    db.Debug().Model(&user).Updates(UsersUpdate{Name: "hello", Age: 0, Active: false})
    
    // 警告:当使用 struct 更新时,GORM只会更新那些非零值的字段
    // 对于下面的操作,不会发生任何更新,"", 0, false 都是其类型的零值
    db.Debug().Model(&user).Updates(User{Name: "", Age: 0, Active: false})
    

    image-20211124083012030

    image-20211124083049901

    2.5 更新选定字段

    如果你想更新或忽略某些字段,你可以使用 SelectOmit

    m1 := map[string]interface{}{
        "name":"",
        "age": 18,
        "active": true,
    
    }
    // UPDATE `users_updates` SET `age`=18,`updated_at`='2021-11-24 08:31:31.716' WHERE `id` = 1
    // 只更新age字段
    db.Debug().Model(&user).Select("age").Updates(m1)
    
    

    2.6 更新排除字段

    m1 := map[string]interface{}{
        "name":"Randy",
        "age": 188,
        "active": false,
    
    }
    // 排除m1中active更新其他的字段
    //  UPDATE `users_updates` SET `age`=188,`name`='Randy',`updated_at`='2021-11-24 08:33:48.312' WHERE `id` = 1
    db.Debug().Model(&user).Omit("active").Updates(m1)
    

    image-20211124083428534

    image-20211124083504638

    2.7 无Hooks更新

    上面的更新操作会自动运行 model 的 BeforeUpdate, AfterUpdate 方法,更新 UpdatedAt 时间戳, 在更新时保存其 Associations, 如果你不想调用这些方法,你可以使用 UpdateColumnUpdateColumns

    // 更新单个属性,类似于 `Update`
    db.Debug().Model(&user).UpdateColumn("name", "hello")
    //// UPDATE users SET name='hello' WHERE id = 111;
    
    // 更新多个属性,类似于 `Updates`
    db.Debug().Model(&user).UpdateColumns(User{Name: "hello", Age: 18})
    //// UPDATE users SET name='hello', age=18 WHERE id = 111;
    

    三、 批量更新

    批量更新时Hooks(钩子函数)不会运行。

    // 批量更新
    // UPDATE `users` SET `age`=18,`name`='xiao_zhi' WHERE id IN (3,4)
    update_res := db.Debug().Table("users_updates").Where("id IN (?)", []int{3, 4}).Updates(map[string]interface{}{"name": "xiao_zhi", "age": 18})
    fmt.Printf("%#v", update_res)
    
    // 使用 `RowsAffected` 获取更新记录总数
    rows := update_res.RowsAffected
    fmt.Printf("%#v", rows)
    
    
    // 使用 struct 更新时,只会更新非零值字段,若想更新所有字段,请使用map[string]interface{}
    db.Debug().Model(User{}).Updates(User{Name: "hello", Age: 18})
    //// UPDATE users SET name='hello', age=18;
    
    // 使用 `RowsAffected` 获取更新记录总数
    db.Debug().Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected
    

    image-20211124084531391

    image-20211124084420612

    四、 使用SQL表达式更新

    先查询表中的第一条数据保存至user变量。

    4.1 查询更新

    var user UsersUpdate
    db.Debug().First(&user)
    fmt.Printf("%#v", user)
    // UPDATE `users_updates` SET `age`=age * 2 + 100,`updated_at`='2021-11-24 08:47:38.193' WHERE `id` = 1
    db.Debug().Model(&user).Update("age", gorm.Expr("age * ? + ?", 2, 100))
    
    

    image-20211124084959280

    image-20211124085019639

    4.2 map更新

    var user UsersUpdate
    db.Debug().First(&user)
    fmt.Printf("%#v", user)
    //  UPDATE `users_updates` SET `age`=age * 2 + 100,`updated_at`='2021-11-24 08:54:32.295' WHERE `id` = 1
    db.Debug().Model(&user).Updates(map[string]interface{}{"age": gorm.Expr("age * ? + ?", 2, 100)})
    
    

    image-20211124085511116

    image-20211124085526432

    4.3 UpdateColumn更新

    var user UsersUpdate
    db.Debug().First(&user)
    fmt.Printf("%#v", user)
    //  UPDATE `users_updates` SET `age`=age - 1 WHERE `id` = 1
    db.Debug().Model(&user).UpdateColumn("age", gorm.Expr("age - ?", 1))
    

    image-20211124085631686

    image-20211124085648143

    4.3 条件更新

    var user UsersUpdate
    db.Debug().First(&user)
    fmt.Printf("%#v", user)
    // UPDATE `users_updates` SET `age`=age - 1 WHERE age > 10 AND `users_updates`.`deleted_at` IS NULL AND `id` = 1
    db.Debug().Model(&user).Where("age > 10").UpdateColumn("age", gorm.Expr("age - ?", 1))
    

    image-20211124085826792

    image-20211124085840916

    4.4 修改Hooks中的值

    如果你想修改 BeforeUpdate, BeforeSave 等 Hooks 中更新的值,你可以使用 scope.SetColumn, 例如:

    func (user *User) BeforeSave(scope *gorm.Scope) (err error) {
      if pw, err := bcrypt.GenerateFromPassword(user.Password, 0); err == nil {
        scope.SetColumn("EncryptedPassword", pw)
      }
    }
    

    五、 其它更新选项

    var user UsersUpdate
    db.Debug().First(&user)
    fmt.Printf("%#v", user)
    // 为 update SQL 添加其它的 SQL
    // UPDATE `users_updates` SET `name`='hello',`updated_at`='2021-11-24 09:01:16.859' WHERE `id` = 1
    db.Debug().Model(&user).Set("gorm:update_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Update("name", "hello")
    

    image-20211124090200431

    image-20211124090213214

    在当下的阶段,必将由程序员来主导,甚至比以往更甚。
  • 相关阅读:
    1221D
    1249E
    D. Yet Another Monster Killing Problem
    大佬传送门
    Zookeeper客户端连接报错
    搭建PXC集群
    Docker分布式环境
    Docker使用
    Docker入门
    MySQL数据库集群概述
  • 原文地址:https://www.cnblogs.com/randysun/p/15626808.html
Copyright © 2020-2023  润新知