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) {
|