Save 会保存所有的字段,即使字段是零值
db.First(&user)
|
更新单个列
当使用 Update 更新单个列时,你需要指定条件,否则会返回 ErrMissingWhereClause 错误,查看 Block Global Updates 获取详情。当使用了 Model 方法,且该对象主键有值,该值会被用于构建条件,例如:
// 条件更新
|
更新多列
Updates 方法支持 struct 和 map[string]interface{} 参数。当使用 struct 更新时,默认情况下,GORM 只会更新非零值的字段
// 根据 `struct` 更新属性,只会更新非零值的字段
|
注意 当通过 struct 更新时,GORM 只会更新非零字段。 如果您想确保指定字段被更新,你应该使用
Select更新选定字段,或使用map来完成更新操作
更新选定字段
如果您想要在更新时选定、忽略某些字段,您可以使用 Select、Omit
// 使用 Map 进行 Select
|
更新 Hook
对于更新操作,GORM 支持 BeforeSave、BeforeUpdate、AfterSave、AfterUpdate 钩子,这些方法将在更新记录时被调用,详情请参阅 钩子
func (u *User) BeforeUpdate(tx *gorm.DB) (err error) {
|
批量更新
如果您尚未通过 Model 指定记录的主键,则 GORM 会执行批量更新
// 根据 struct 更新
|
阻止全局更新
如果在没有任何条件的情况下执行批量更新,默认情况下,GORM 不会执行该操作,并返回 ErrMissingWhereClause 错误
对此,你必须加一些条件,或者使用原生 SQL,或者启用 AllowGlobalUpdate 模式,例如:
db.Model(&User{}).Update("name", "jinzhu").Error // gorm.ErrMissingWhereClause
|
更新的记录数
获取受更新影响的行数
// 通过 `RowsAffected` 得到更新的记录数
|
高级选项
使用 SQL 表达式更新
GORM 允许使用 SQL 表达式更新列,例如:
// product 的 ID 是 `3`
|
并且 GORM 也允许使用 SQL 表达式、自定义数据类型的 Context Valuer 来更新,例如:
// 根据自定义数据类型创建
|
根据子查询进行更新
使用子查询更新表
db.Model(&user).Update("company_name", db.Model(&Company{}).Select("name").Where("companies.id = users.company_id"))
|
不使用 Hook 和时间追踪
如果您想在更新时跳过 Hook 方法且不追踪更新时间,可以使用 UpdateColumn、UpdateColumns,其用法类似于 Update、Updates
// 更新单个列
|
Returning Data From Modified Rows
Return changed data, only works for database support Returning, for example:
// return all columns
|
Check Field has changed?
GORM provides Changed method could be used in Before Update Hooks, it will return the field changed or not
The Changed method only works with methods Update, Updates, and it only checks if the updating value from Update / Updates equals the model value, will return true if it is changed and not omitted
func (u *User) BeforeUpdate(tx *gorm.DB) (err error) {
|
Change Updating Values
To change updating values in Before Hooks, you should use SetColumn unless it is a full updates with Save, for example:
func (user *User) BeforeSave(tx *gorm.DB) (err error) {
|