codecamp

GORM 创建

创建记录

user := User{Name: "张三", 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: "张三"}, {Name: "李四"}, {Name: "王五"}}
db.Create(&users)

for _, user := range users {
  user.ID // 1,2,3
}

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

var users = []User{{name: "张三_1"}, ...., {Name: "张三_10000"}}

// 数量为 100
db.CreateInBatches(users, 100)

Upsert和Create With Associations 也支持批量插入

注意:使用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: "张三", 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": "张三", "Age": 18,
})

// batch insert from `[]map[string]interface{}{}`
db.Model(&User{}).Create([]map[string]interface{}{
  {"Name": "李四", "Age": 19},
  {"Name": "王五", "Age": 20},
})

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

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

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

// 通过 map 创建记录
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)"));

// 通过自定义类型创建记录
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:     "张三",
  Location: Location{X: 100, Y: 100},
})
// INSERT INTO `users` (`name`,`location`) VALUES ("张三",ST_PointFromText("POINT(100 100)"))


GORM 连接数据库
GORM 查询
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }