创建

  小知识:在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,或者""怎么办?

  如果出现这种情况,有两种办法可以解决

  1. 指针
  2. 实现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}