user := User{Name: "張三", Age: 18, Birthday: time.Now()}
result := db.Create(&user) // 通過(guò)數(shù)據(jù)的指針來(lái)創(chuàng)建
user.ID // 返回插入數(shù)據(jù)的主鍵
result.Error // 返回 error
result.RowsAffected // 返回插入記錄的條數(shù)
創(chuàng)建記錄并更新給出的字段
db.Select("Name", "Age", "CreatedAt").Create(&user)
// INSERT INTO `users` (`name`,`age`,`created_at`) VALUES ("jinzhu", 18, "2020-07-04 11:05:21.775")
創(chuàng)建一個(gè)記錄且一同忽略傳遞給略去的字段值
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")
要有效地插入大量記錄,請(qǐng)將一個(gè) slice 傳遞給 Create 方法。 GORM 將生成單獨(dú)一條SQL語(yǔ)句來(lái)插入所有數(shù)據(jù),并回填主鍵的值,鉤子方法也會(huì)被調(diào)用
var users = []User{{Name: "張三"}, {Name: "李四"}, {Name: "王五"}}
db.Create(&users)
for _, user := range users {
user.ID // 1,2,3
}
使用 CreateInBatches 分批創(chuàng)建時(shí),你可以指定每批的數(shù)量,例如:
var users = []User{{name: "張三_1"}, ...., {Name: "張三_10000"}}
// 數(shù)量為 100
db.CreateInBatches(users, 100)
Upsert和Create With Associations 也支持批量插入
注意:使用CreateBatchSize選項(xiàng)初始化GORM時(shí),所有的創(chuàng)建&關(guān)聯(lián)INSERT都將遵循該選項(xiàng)
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
CreateBatchSize: 1000,
})
db := db.Session(&gorm.Session{CreateBatchSize: 1000})
users = [5000]User{{Name: "張三", Pets: []Pet{pet1, pet2, pet3}}...}
db.Create(&users)
// INSERT INTO users xxx (5 batches)
// INSERT INTO pets xxx (15 batches)
GORM允許用戶(hù)定義的鉤子有BeforeSave,BeforeCreate,AfterSave,AfterCreate創(chuàng)建記錄時(shí)將調(diào)用這些鉤子方法
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
u.UUID = uuid.New()
if u.Role == "admin" {
return errors.New("invalid role")
}
return
}
如果您想跳過(guò)鉤子方法,您可以使用SkipHooks會(huì)話(huà)模式,例如:
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)
GORM 支持根據(jù)map[string]interface{}和[]map[string]interface{}{}創(chuàng)建記錄,例如:
db.Model(&User{}).Create(map[string]interface{}{
"Name": "張三", "Age": 18,
})
// batch insert from `[]map[string]interface{}{}`
db.Model(&User{}).Create([]map[string]interface{}{
{"Name": "李四", "Age": 19},
{"Name": "王五", "Age": 20},
})
注意:根據(jù)map創(chuàng)建記錄時(shí),association不會(huì)被調(diào)用,且主鍵也不會(huì)自動(dòng)填充
GORM允許使用SQL表達(dá)式插入數(shù)據(jù),有兩種方法實(shí)現(xiàn)這個(gè)目標(biāo)。根據(jù)map[string]interface{}或自定義數(shù)據(jù)類(lèi)型創(chuàng)建,例如:
// 通過(guò) map 創(chuàng)建記錄
db.Model(User{}).Create(map[string]interface{}{
"Name": "張三",
"Location": clause.Expr{SQL: "ST_PointFromText(?)", Vars: []interface{}{"POINT(100 100)"}},
})
// INSERT INTO `users` (`name`,`location`) VALUES ("張三",ST_PointFromText("POINT(100 100)"));
// 通過(guò)自定義類(lèi)型創(chuàng)建記錄
type Location struct {
X, Y int
}
// Scan 方法實(shí)現(xiàn)了 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: "張三",
Location: Location{X: 100, Y: 100},
})
// INSERT INTO `users` (`name`,`location`) VALUES ("張三",ST_PointFromText("POINT(100 100)"))
更多建議: