在使用 github.com/jinzhu/gorm 这个orm包时,跟其他语言一样当某个字段设有默认值的情况下,不传入值时会采用默认值。但是当传入这个字段的零值时,会插入默认值而不是零值。
场景:
//定义一个User结构体作为表结构model
type User struct {
ID int64
Name string `gorm:"default:'xixi'"`
Age int64
}
func main() {
db, err := gorm.Open("mysql", "test:test@tcp(10.3.6.194:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.AutoMigrate(&User{})
u := User{
Name: "",
Age: 18,
}
db.Debug().Create(&u)
}
在这段代码里,Name字段默认是xixi,毫无疑问我在插入时不指定Name字段时默认值是xixi。可是当我给传了一个空字符串(string 类型的零值),数据库里保存的不是空字符串而是xixi这个默认值。这就是说在这个包里,通过tag定义字段的默认值,在创建记录时候生成的sql语句会排除没有值或为 零值 的字段这样在插入数据库就会插入字段的默认值。这里我试用了string类型的零值,所以name字段插入的是默认值而非空字符串。
解决方式:
- 使用指针
- 实现 Scanner/Valuer接口
使用指针:
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
// User struct
type User struct {
ID int64
Name *string `gorm:"default:'xixi'"`
Age int64
}
func main() {
db, err := gorm.Open("mysql", "test:test@tcp(10.3.6.194:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.AutoMigrate(&User{})
u := User{
Name: new(string),
Age: 19,
}
db.Debug().Create(&u)
}
使用指针后再次插入就能得到空字符串。
实现 Scanner/Valuer接口:
package main
import (
"database/sql"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
// User struct
type User struct {
ID int64
Name sql.NullString `gorm:"default:'xixi'"`
Age int64
}
func main() {
db, err := gorm.Open("mysql", "test:test@tcp(10.3.6.194:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.AutoMigrate(&User{})
u := User{
Name: sql.NullString{String: "", Valid: true},
Age: 20,
}
db.Debug().Create(&u)
}
就bb这么多,当然你也可以使用debug方法来打印出具体的SQL语句。