GORM基于map执行Create操作时主键回填机制疑问
关于GORM map创建记录「主键不回填」的说明
你对文档描述的理解存在偏差:文档提到的「使用map方式创建记录时,主键值不会被回填」,不是指数据库不会为插入的记录生成主键,而是指GORM不会在插入操作完成后,将数据库自动生成的主键值,反向赋值给你调用Create方法时传入的Go变量。
你在MySQL中查询到主键正常填充,是数据库层面的行为:你的User结构体嵌入了gorm.Model,其自带的ID主键配置了自增属性,插入记录时MySQL会自动生成连续的自增ID存入表中,这个逻辑和GORM是否做值回填没有关联。
你可以通过以下测试代码直观感受到「不回填」的实际表现:
// 1. 结构体插入场景:GORM会回填主键 newUser := User{Name: "struct_test", Age: 18} db.Create(&newUser) fmt.Println(newUser.ID) // 执行后会正常打印数据库生成的自增ID // 2. 单map插入场景:GORM不会回填主键 userMap := map[string]interface{}{"Name": "map_test", "Age": 18} db.Model(&User{}).Create(userMap) fmt.Println(userMap["ID"]) // 执行后打印结果为nil,map中不存在GORM回填的主键值 // 3. map切片批量插入场景:同样不会回填 userMaps := []map[string]interface{}{ {"Name": "batch_test1", "Age": 18}, {"Name": "batch_test2", "Age": 20}, } db.Model(&User{}).Create(userMaps) for _, m := range userMaps { fmt.Println(m["ID"]) // 两个map打印ID的结果均为nil }
补充说明:如果你在传入的map中手动指定了主键值,该值会正常写入数据库,只是数据库端自动生成的字段值(包括自增主键、默认时间字段等)都不会被同步回你传入的map变量中。
内容的提问来源于stack exchange,提问作者Yuanhao
相关产品推荐
相关产品推荐

