레코드 생성
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()} |
Create()
함수를 통해 여러 레코드를 동시에 생성할수도 있습니다.
users := []*User{ |
주의할점 구조체를 직접 ‘create’ 함수에 넣지 마세요, 대신 포인터를 넣어주세요.
선택한 필드로 레코드 만들기
Create a record and assign a value to the fields specified.
db.Select("Name", "Age", "CreatedAt").Create(&user) |
Create a record and ignore the values for fields passed to omit.
db.Omit("Name", "Age", "CreatedAt").Create(&user) |
Batch Insert
효율적으로 많은 레코드를 만들기 위해서, slice를 Create
메소드에 넣어주세요. GORM은 단 하나의 SQL 구문을 작성하여 모든 데이터를 삽입합니다 또한 hook methods, primary key 값 자동 삽입등이 이를 기점으로 하여 실행됩니다. 이를 일정한 배치 단위로 나누어서 트랜잭션으로 처리할 수 있습니다.
var users = []User{{Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}} |
CreateInBatches
를 활용하여 배치 사이즈를 결정할 수 있습니다, e.g:
var users = []User{{Name: "jinzhu_1"}, ...., {Name: "jinzhu_10000"}} |
Batch Insert는 Upset와 Create With Associtations에도 지원됩니다.
주의할점: GORM을
CreateBatchSize
옵션과 함께 생성할 경우, 모든INSERT
구문은 레코드 생성시 해당 배치 옵션을 따를것입니다.
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{ |
Hooks 생성하기
GORM은 BeforeSave
,BeforeCreate
,AfterSave
,AfterCreate
등과 같은 사용자가 정의한 hook을 구현하여 사용할 수 있습니다. 이런 hook 메소드들은 레코드를 만들때 호출 됩니다, Hooks를 참고하여 좀 더 자세한 생명주기에 관하여 참고해보세요.
func (u *User) BeforeCreate(tx *gorm.DB) (err error) { |
만일 Hooks
메소드들을 생략하고 싶으시다면, SkipHooks
를 session mode에서 활용할 수 있습닏, 예시:
DB.Session(&gorm.Session{SkipHooks: true}).Create(&user) |
Map으로 생성하기
GORM은 map[string] interface{}
및 []map[string] interface{}{}
를 활용한 레코드 생성을 지원합니다, 예시:
db.Model(&User{}).Create(map[string]interface{}{ |
주의할점 map 자료구조를 활용한 레코드 생성시, hooks은 실행되지 않으며 기본키가 채워지지 안흥며 연결이 저장되지 않습니다.
SQL Expression/Context Valuer로 생성
GORM은 SQL을 활용한 데이터 삽입을 지원합니다. SQL을 활용하기 위하여는 두 가지 방법을 사용할 수 있습니다. map[string] interface{}
혹은 사용자 정의 데이터 타입을 활용할 수 있습니다. 예시:
// map을 활용한 레코드 생성 |
고급
Create With Associations
연관(associations) 이 있는 일부 데이터를 작성할 때 association 값이 0 값이 아닌 경우 해당 association이 upsert 되고 해당 Hooks
메소드가 호출됩니다.
type CreditCard struct { |
Select
, Omit
를 사용하여 associations를 스킵 할 수 있습니다. 예시:
db.Omit("CreditCard").Create(&user) |
기본 값
default
태그를 사용하여 필드의 기본값을 정의 할 수 있습니다. 예를 들면 다음과 같습니다.
type User struct { |
Then the default value will be used when inserting into the database for zero-value fields
NOTE
0
,''
,false
와 같은 값들은 지정된 기본값으로 데이터베이스에 저장되지 않습니다, 대신에 포인터 타입 혹은 Scanner/Value를 활용해주세요, 예시:
type User struct { |
NOTE 데이터베이스에 기본 값 또는 가상/생성 값이 있는 필드에 대해
default
태그를 설정해야 합니다. 데이터베이스 마이그레이션 할 때 기본 값을 정의하는 부분을 건너뛰려면 다음과 같이default:(-)
를 사용할 수 있습니다. 예시:
type User struct { |
NOTE****SQLite는 특정 레코드에 대하여 batch insert를 실행시 기본값을 지원하지 않습니다. SQLite insert 구문을 참고하세요. For example:
type Pet struct {
Name string `gorm:"default:cat"`
}
// SQLite는 다음과 같은 구문을 지원하지 않으므로 GORM은 잘못된 SQL을 생성하고 에러를 일으킬 것입니다.
// 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"
}
}issues#6335를 통해 더 자세한 사항을 볼 수 있습니다.
Virtual/generated 값을 활용하려면 creating/dupdating 권한을 비활성화해야할 수 있습니다, Field-Level Permission을 참고해 주세요.
Upsert / On Conflict
GORM은 다른 데이터베이스와 상호 운용가능한 Upsert를 지원합니다.
import "gorm.io/gorm/clause" |
Also checkout FirstOrInit
, FirstOrCreate
on Advanced Query
Checkout Raw SQL and SQL Builder for more details