小知识:在GORM语句前面增加.DeBug(),即可看到执行的Sql语句
db.NewRecord(user)
这里发现插入时并没有插入主键,但是这里主键是自增的,需要注意的是,传入的user实例的id被赋值了
type User struct {
ID int64
Name string
Age int64
}
func main() {
db, err := gorm.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
// 自动迁移
db.AutoMigrate(&User{})
user := User{Name: "武旭飞", Age: 20}
fmt.Println(user, db.NewRecord(user)) // 主键为空返回`true`
db.Debug().Create(&user) // 创建user
fmt.Println(user, db.NewRecord(user)) // 创建`user`后返回`false`
}
{0 武旭飞 20} true
(C:/Users/68725/Desktop/leetcode/main.go:27)
[2022-05-12 17:46:43] [1.21ms] INSERT INTO `users` (`name`,`age`) VALUES ('武旭飞',20)
[1 rows affected or returned ]
{4 武旭飞 20} false
设置默认值
可以通过 tag 定义字段的默认值,比如:
type User struct {
ID int64
Name string `gorm:"default:'飞飞飞'"`
Age int64
}
func main() {
db, err := gorm.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
// 自动迁移
db.AutoMigrate(&User{})
user := User{Age: 3}
db.Debug().Create(&user) // 创建user
fmt.Println(user)
}
通过tag设置默认值的字段,在GORM上传Sql语句的时候,会自动将值为零值的字段移除掉,即不写入Sql语句中,带记录插入数据库后,GORM会自动从数据库加载字段的默认值赋值给结构体实例。
(C:/Users/68725/Desktop/leetcode/main.go:25)
[2022-05-12 17:54:15] [1.22ms] INSERT INTO `users` (`age`) VALUES (3)
[1 rows affected or returned ]
(C:/Users/68725/Desktop/leetcode/main.go:25)
[2022-05-12 17:54:15] [1.06ms] SELECT `name` FROM `users` WHERE (id = 5)
[1 rows affected or returned ]
{5 飞飞飞 3}
进程 已完成,退出代码为 0
想要插入零值
由于设置了默认值之后,所有类型的零值,都不会保存到数据库中,而是保存他们的默认值,这就出现了一个问题:如果我想存0,或者""怎么办?
如果出现这种情况,有两种办法可以解决
- 指针
- 实现Scanner/Valuer的接口
指针
使用指针方式实现零值存入数据库
// 使用指针
type User struct {
ID int64
Name *string `gorm:"default:'飞飞飞'"`
Age int64
}
func main() {
db, err := gorm.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
// 自动迁移
db.AutoMigrate(&User{})
user := User{Name: new(string), Age: 18}
db.Debug().Create(&user) // 创建user
fmt.Println(user)
}
[2022-05-12 17:59:18] [3.79ms] INSERT INTO `users` (`name`,`age`) VALUES ('',18)
[1 rows affected or returned ]
{1 0xc0001d27f0 18}
实现Scanner/Valuer的接口
使用Scanner/Valuer接口方式实现零值存入数据库
// 使用 Scanner/Valuer
type User struct {
ID int64
Name sql.NullString `gorm:"default:'飞飞飞'"` // sql.NullString 实现了Scanner/Valuer接口
Age int64
}
func main() {
db, err := gorm.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
// 自动迁移
db.AutoMigrate(&User{})
user := User{Name: sql.NullString{Valid: true}, Age: 18}
db.Debug().Create(&user) // 创建user
fmt.Println(user)
}
[2022-05-12 18:01:03] [2.50ms] INSERT INTO `users` (`name`,`age`) VALUES ('',18)
[1 rows affected or returned ]
{1 { true} 18}