一七零、GORM值为0或者空字符串的时候不能被更新创建的五种解决办法
在使用grom时,如果用结构体的形式,对数据库进行更新时,会出现一个问题:当我们想要将某个字段的值更新为0&空字符串,执行update之后会发现该数据实际上并没有被更新。
例如有如下数据表:
id | name | score | desc |
---|---|---|---|
1 | 王五 | 99 | 调皮 |
有如下结构体:
type Student struct{Id int32 `gorm:"type:int(11);column:id;primaryKey;autoIncrement;comment:" json:"id"`Name string `gorm:"type:varchar(100);column:name;not null;default:'';comment:姓名"`Score int32 `gorm:"type:int(11);column:score;comment:分数"`Desc string `gorm:"type:varchar(1000);column:desc;default:'';comment:备注"`
}
当我们执行以下操作后
upStudent := Student{Id :1,Name :张三,Score :0,Desc:""
}db.Model(&student).Where("id=?", Student.Id).Updates(Student)
会发现,执行成功之后,score依旧等于99,Desc也是"调皮"
解决方法一:结合 Select 和 Omit
fields := []string{"id","name","score",”desc“}
db.Model(&Student).Select(fields).Where("id=?", Student.Id).Updates(Student)
// 或者Omit
db.Model(&Student{}).Omit("id").Where("id = ?", upStudent.Id).Updates(upStudent)
解决方法二:使用Save
注:Save 会保存所有的字段,即使字段是零值;保存是一个组合函数。 如果保存值不包含主键,它将执行 Create,否则它将执行 Update (包含所有字段)。
db.Model(&Student).Where("id=?", Student.Id).Save(Student)
解决方法三:使用map接口,即map[string]interface{} (推荐)
注:我们使用的是protobuf定义了的结构时,转换成map有些许麻烦。
values := map[string]interface{}{"id": upStudent.Id,"name": upStudent.Name,"score": upStudent,Score,"desc":upStudent,Desc,}
db.Model(&Student).Where("id=?", Student.Id).Updates(values)
解决方法三:使用map接口,即map[string]interface{} (推荐)
注:我们使用的是protobuf定义了的结构时,转换成map有些许麻烦。
values := map[string]interface{}{"id": upStudent.Id,"name": upStudent.Name,"score": upStudent,Score,"desc":upStudent,Desc,}
db.Model(&Student).Where("id=?", Student.Id).Updates(values)
解决方法四:逐字段单独赋值
注:我们使用的是protobuf定义了的结构时,转换成map有些许麻烦。
upStudent := Student{Id : 1,
}db.Model(&Student{}).Where("id = ?", upStudent.Id).Update("score", 0).Update("name", "张三").Update("desc", "")
解决方法五:定义 Struct 时将字段设置为指针类型
通过将字段定义为指针类型,可以避免默认忽略 0 值的问题。同样适用于空字符串。
score := int32(0)
name := "张三"
desc := ""
upStudent := Student{Id : 1,Name : &name,Score : &score,Desc: &desc,
}
db.Model(&Student{}).Where("id = ?", upStudent.Id).Updates(upStudent)