Создание записи
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()} |
Мы также можем создать несколько записей с помощью Create()
:
users := []*User{ |
ПРИМЕЧАНИЕ В
create
необходимо передавать указатель на структуру, а не значение.
Создание записи с указанными полями
При создании записи, используя Select, мы можем указать в какие именно поля необходимо занести значения.
db.Select("Name", "Age", "CreatedAt").Create(&user) |
Также при создании записи, используя Omit, мы можем указать какие поля необходимо игнорировать.
db.Omit("Name", "Age", "CreatedAt").Create(&user) |
Пакетная вставка
Чтобы эффективно вставлять большое количество записей, в метод Create
следует передавать слайс. GORM сгенерирует одну инструкцию SQL для вставки всех данных и обратного заполнения значений первичного ключа, также будут вызваны методы перехвата (hook). Транзакция начнется, когда записи можно будет разделить на несколько пакетов.
var users = []User{{Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}} |
Вы можете указать batch size при создании с помощью CreateInBatches
, например:
var users = []User{{Name: "jinzhu_1"}, ...., {Name: "jinzhu_10000"}} |
Batch Insert также поддерживается при использовании Upsert и Create With Associations
ПРИМЕЧАНИЕ При инициализации GORM, в конфигурации, с помощью параметра
CreateBatchSize
можно указать размер пакета и всеINSERT
будут учитывать этот параметр при создании записей и ассоциаций
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{ |
Создание хуков
GORM позволяет реализовать пользовательские перехватчики для beforeSave
, beforeCreate
, afterSave
, afterCreate
. Эти методы перехвата будут вызываться при создании записи, для получения подробной информации о жизненном цикле обратитесь к Hooks
func (u *User) BeforeCreate(tx *gorm.DB) (err error) { |
Если вы хотите пропустить методы Hooks
, вы можете использовать режим сессии, передав в качестве параметра SkipHooks
, например:
DB.Session(&gorm.Session{SkipHooks: true}).Create(&user) |
Create с помощью Map(карты)
GORM поддерживает создание из map[string]interface{}
и[]map[string]interface{}{}
, например:
db.Model(&User{}).Create(map[string]interface{}{ |
ПРИМЕЧАНИЕ При создании на основе map перехватчики не будут вызваны, ассоциации не будут сохранены, а значения первичных ключей не будут заполнены
Метод Create с помощью SQL выражения/значения контекста
GORM allows insert data with SQL expression, there are two ways to achieve this goal, create from map[string]interface{}
or Customized Data Types, for example:
// Создать из map |
Дополнительно
Create со связями
When creating some data with associations, if its associations value is not zero-value, those associations will be upserted, and its Hooks
methods will be invoked.
type CreditCard struct { |
You can skip saving associations with Select
, Omit
, for example:
db.Omit("CreditCard").Create(&user) |
Значения по умолчанию
You can define default values for fields with tag default
, for example:
type User struct { |
Then the default value will be used when inserting into the database for zero-value fields
NOTE Any zero value like
0
,''
,false
won’t be saved into the database for those fields defined default value, you might want to use pointer type or Scanner/Valuer to avoid this, for example:
type User struct { |
NOTE You have to setup the
default
tag for fields having default or virtual/generated value in database, if you want to skip a default value definition when migrating, you could usedefault:(-)
, for example:
type User struct { |
NOTE SQLite doesn’t support some records are default values when batch insert. See SQLite Insert stmt. For example:
type Pet struct {
Name string `gorm:"default:cat"`
}
// In SQLite, this is not supported, so GORM will build a wrong SQL to raise error:
// INSERT INTO `pets` (`name`) VALUES ("dog"),(DEFAULT) RETURNING `name`
db.Create(&[]Pet{{Name: "dog"}, {}})A viable alternative is to assign default value to fields in the hook, e.g.
func (p *Pet) BeforeCreate(tx *gorm.DB) (err error) {
if p.Name == "" {
p.Name = "cat"
}
}You can see more info in issues#6335
When using virtual/generated value, you might need to disable its creating/updating permission, check out Field-Level Permission
Upsert (Создать или обновить) / При конфликте
GORM provides compatible Upsert support for different databases
import "gorm.io/gorm/clause" |
Also checkout FirstOrInit
, FirstOrCreate
on Advanced Query
Checkout Raw SQL and SQL Builder for more details