GORM创建(插入)数据

创建记录

user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
result := db.Create(&user) // 通过数据的指针来创建
user.ID             // 返回插入数据的主键
result.Error        // 返回 error
result.RowsAffected // 返回插入记录的条数

用指定的字段创建记录

创建记录并更新给出的字段。

db.Select("Name", "Age", "CreatedAt").Create(&user) // INSERT INTO `users` (`name`,`age`,`created_at`) VALUES ("jinzhu", 18, "2020-07-04 11:05:21.775")

创建一个记录且一同忽略传递给略去的字段值。

db.Omit("Name", "Age", "CreatedAt").Create(&user) // INSERT INTO `users` (`birthday`,`updated_at`) VALUES ("2020-01-01 00:00:00.000", "2020-07-04 11:05:21.775")

批量插入

要有效地插入大量记录,请将一个 slice 传递给 Create 方法。 GORM 将生成单独一条SQL语句来插入所有数据,并回填主键的值,钩子方法也会被调用。

var users = []User{{Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}} db.Create(&users) for _, user := range users { user.ID // 1,2,3 }

使用 CreateInBatches 分批创建时,你可以指定每批的数量,例如:

var users = []User{{name: "jinzhu_1"}, ...., {Name: "jinzhu_10000"}} // 数量为 100 db.CreateInBatches(users, 100)
Upsert和Create With Assoiciations 也支持批量插入

注意 使用CreateBatchSize 选项初始化 GORM 时,所有的创建& 关联 INSERT 都将遵循该选项

db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{ CreateBatchSize: 1000, }) db := db.Session(&gorm.Session{CreateBatchSize: 1000}) users = [5000]User{{Name: "jinzhu", Pets: []Pet{pet1, pet2, pet3}}...} db.Create(&users) // INSERT INTO users xxx (5 batches) // INSERT INTO pets xxx (15 batches)
创建钩子

GORM 允许用户定义的钩子有 BeforeSave, BeforeCreate, AfterSave, AfterCreate 创建记录时将调用这些钩子方法,请参考

func (u *User) BeforeCreate(tx *gorm.DB) (err error) { u.UUID = uuid.New() if u.Role == "admin" { return errors.New("invalid role") } return }

如果您想跳过 钩子 方法,您可以使用 SkipHooks 会话模式,例如:

DB.Session(&gorm.Session{SkipHooks: true}).Create(&user) DB.Session(&gorm.Session{SkipHooks: true}).Create(&users) DB.Session(&gorm.Session{SkipHooks: true}).CreateInBatches(users, 100)
根据 Map 创建

GORM 支持根据 map[string]interface{} 和 []map[string]interface{}{} 创建记录,例如

db.Model(&User{}).Create(map[string]interface{}{ "Name": "jinzhu", "Age": 18, }) // batch insert from `[]map[string]interface{}{}` db.Model(&User{}).Create([]map[string]interface{}{ {"Name": "jinzhu_1", "Age": 18}, {"Name": "jinzhu_2", "Age": 20}, })

注意: 根据 map 创建记录时,association 不会被调用,且主键也不会自动填充

使用 SQL 表达式、Context Valuer 创建记录

GORM 允许使用 SQL 表达式插入数据,有两种方法实现这个目标。根据 map[string]interface{} 或 自定义数组类型

// 通过 map 创建记录 db.Model(User{}).Create(map[string]interface{}{ "Name": "jinzhu", "Location": clause.Expr{SQL: "ST_PointFromText(?)", Vars: []interface{}{"POINT(100 100)"}}, }) // INSERT INTO `users` (`name`,`location`) VALUES ("jinzhu",ST_PointFromText("POINT(100 100)")); // 通过自定义类型创建记录 type Location struct { X, Y int } // Scan 方法实现了 sql.Scanner 接口 func (loc *Location) Scan(v interface{}) error { // Scan a value into struct from database driver } func (loc Location) GormDataType() string { return "geometry" } func (loc Location) GormValue(ctx context.Context, db *gorm.DB) clause.Expr { return clause.Expr{ SQL: "ST_PointFromText(?)", Vars: []interface{}{fmt.Sprintf("POINT(%d %d)", loc.X, loc.Y)}, } } type User struct { Name string Location Location } db.Create(&User{ Name: "jinzhu", Location: Location{X: 100, Y: 100}, }) // INSERT INTO `users` (`name`,`location`) VALUES ("jinzhu",ST_PointFromText("POINT(100 100)"))
本作品采用《CC 协议》,转载必须注明作者和本文链接
good good study day day up
讨论数量: 2

老兄你是不是跑错片场了

1年前 评论

跑错片场了,老铁!

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!