gorm更新数据遇到的空值问题
package gorm_tests import ( "fmt" "github.com/fatih/structs" "github.com/go-playground/validator/v10" "github.com/stretchr/testify/require" "gorm.io/driver/mysql" "gorm.io/gorm" "testing" ) // 参考文档: // Golang结构体校验:https://juejin.cn/post/6900375680358285325 // Golang结构体校验validator库:https://www.cnblogs.com/jiujuan/p/13823864.html const ( studentTableName = "student" ) // Notice 因为要用structs转成的map修改数据库,所以需要structs与gorm标签的值一一对应 type Student struct { ID uint `gorm:"primaryKey;column:id" structs:"id"` // id在数据库中自动递增生成,不用校验 Name string `gorm:"column:name" structs:"name" validate:"required,min=1,max=20"` // 1 <= len <= 20 Age uint8 `gorm:"column:age" structs:"age" validate:"required,max=150"` // 最大150 Email string `gorm:"column:email" structs:"email" validate:"required,min=1"` // 1 <= len Notice required设置后不能传0 Score float32 `gorm:"column:score" structs:"score" validate:"min=0"` Notes string `gorm:"column:notes" structs:"notes"` } func (s Student) TableName() string { return studentTableName } func genDb() (*gorm.DB, error) { dsn := "root:123@tcp(192.168.110.175:3307)/whw?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) fmt.Println("db: ", db) return db, err } // Updates方法用结构体更新,无法更新为零值 func TestS1(t *testing.T) { s1 := Student{ ID: 1, Name: "rrrr`12", Age: 12, // Notice Age设置了validate为required,所以不能传0!传0的话无法通过校验!! Email: "22222@qq.com", Score: 0, Notes: "", } // validator校验 va := validator.New() errVa := va.Struct(s1) if errVa != nil { fmt.Println("errVa: ", errVa) return } db, errDB := genDb() require.Equal(t, errDB, nil) // Notice 注意这里用 .Error errUp := db.Table(studentTableName).Where("id = ?", s1.ID).Updates(&s1).Error require.Equal(t, errUp, nil) // Notice: 运行结束后,Notes值不能改成空字符串!!!Score不能改成0!!! } // Updates方法用map更新,但是需要注意,structs转成的map携带所有字段,如果有不想更新的字段需要"过滤"一下 func TestS2(t *testing.T) { s1 := Student{ ID: 1, Name: "naruto", Age: 12, // Notice Age设置了validate为required,所以不能传0!传0的话无法通过校验!! Email: "22222@qq.com", Score: 0, Notes: "", } // validator校验 va := validator.New() errVa := va.Struct(s1) if errVa != nil { fmt.Println("errVa: ", errVa) return } db, errDB := genDb() require.Equal(t, errDB, nil) // 结构体先转map s1Map := structs.Map(&s1) // key都有 fmt.Println("s1Map: ", s1Map) // map[age:12 email:22222@qq.com id:1 name:naruto notes: score:0] // Notice 哪些字段不想跟着更新,过滤一下,模拟实际场景就用id了~ updateMap := make(map[string]interface{}) for key := range s1Map { // 跟structs标签值对应 if key == "id" { continue } updateMap[key] = s1Map[key] } fmt.Println("updateMap: ", updateMap) // map[age:12 email:22222@qq.com name:naruto notes: score:0] // 使用map更新,可以更新为零值 // .Error errUpdate := db.Table(studentTableName).Where("id = ?", s1.ID).Updates(updateMap).Error require.Equal(t, errUpdate, nil) }
~~~