이번 포스팅에서는 go를 이용하여 프로그램을 작성할 때, ORM을 이용한 개발을 하기 위해서 GORM에 대해서 정리하도록 하겠습니다. GORM은 go를 위한 object relation mapping(ORM)으로 Go를 위한 ORM 프로젝트 중에서는 document도 매우 준수하고 star도 가장 많이 보유하였기에 정리해보도록 하겠습니다. GORM Docs를 보고 기능들을 정리하였습니다.
GORM에서 Entity를 정의하는 방법은 Go에서 일반전인 구조체를 정의하는 것과 같습니다. 다만, tag기능을 이용하여 옵션을 줄 수 있습니다.
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}
//gorm에서는 위와 같은 Model 구조체가 기본적으로 정의되어 있습니다.
type User struct {
gorm.Model
Name string
Age sql.NullInt64
Birthday *time.Time
Email string `gorm:"type:varchar(100);unique_index"`
Role string `gorm:"size:255"` // set field size to 255
MemberNumber *string `gorm:"unique;not null"` // set member number to unique and not null
Num int `gorm:"AUTO_INCREMENT"` // set num to auto incrementable
Address string `gorm:"index:addr"` // create index with name `addr` for address
IgnoreMe int `gorm:"-"` // ignore this field
}
GORM에서 지원하는 tag들은 다음과 같습니다.
Tag | 기능 |
Column | column명 지정 |
Type | 데이터 타입 지정 |
Size | column 크기 지정, 디폴트값은 255 |
PRIMARY_KEY | primary key로 지정 |
UNIQUE | unique 지정 |
DEFAULT | default 값 지정 |
PRECISION | precision 지정 (값 자리수) |
NOT NULL | NOT NULL로 지정 |
AUTO_INCREMENT | 자동 증가로 지정 |
INDEX | 특정 이름으로 인덱스 지정, 없을시에 복합 인덱스 생성 |
UNIQUE_INDEX | INDEX와 비슷하지만, 유일한 인덱스를 생성 |
EMBEDDED | 구조체를 임베디드로 설정 |
EMBEDDED_PREFIX | 구조체의 prefix 이름을 임베디드 설정 |
- | 필드를 무시함 |
GORM에서는 association들을 위한 tag도 지원합니다.
Tag | 기능 |
MANY2MANY | Join 데이블명 지정 |
FOREIGNKEY | foreign key로 지정 |
ASSOCIATION_FOREIGNKEY | association foreign key 지정 |
POLYMORPHIC | polymorphic type으로 지정 |
POLYMORPHIC_VALUE | polymorphic value으로 지정 |
JOINTABLE_FOREIGNKEY | foreign key of jointable 지정 |
ASSOCIATION_JOINTABLE_FOREIGNKEY | association foreign key of jointable로 지정 |
SAVE_ASSOCIATIONS | AutoSave associations or not |
ASSOCIATION_AUTOUPDATE | AutoUpdate associations or not |
ASSOCIATION_AUTOCREATE | AutoCreate associations or not |
ASSOCIATION_SAVE_REFERENCE | AutoSave associations reference or not |
PRELOAD | Auto Preload associations or not |
다음은 Docs에서 정리된 convention에 대해서 적어보도록 하겠습니다.
- gorm.Model은 GORM에서 정의한 기본적인 struct로 쉽게 임베딩시켜서 사용할 수 있습니다.
- GORM에서는 field명이 "ID"일 경우에 기본적으로 PK로 인식합니다.
- 테이블명은 구조체의 복수형으로 합니다.
type User struct {} // default table name is `users`
// Set User's table name to be `profiles`
func (User) TableName() string {
return "profiles"
}
func (u User) TableName() string {
if u.Role == "admin" {
return "admin_users"
} else {
return "users"
}
}
// Disable table name's pluralization, if set to true, `User`'s table name will be `user`
db.SingularTable(true)
- 테이블명은 지정하세요.
// Create `deleted_users` table with struct User's definition
db.Table("deleted_users").CreateTable(&User{})
var deleted_users []User
db.Table("deleted_users").Find(&deleted_users)
//// SELECT * FROM deleted_users;
db.Table("deleted_users").Where("name = ?", "jinzhu").Delete()
//// DELETE FROM deleted_users WHERE name = 'jinzhu';
- default table명을 바꿀 수 있습니다. DefaultTableNameHandler를 정의합니다.
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return "prefix_" + defaultTableName;
}
- column명은 lower snake case로 합니다.
type User struct {
ID uint // column name is `id`
Name string // column name is `name`
Birthday time.Time // column name is `birthday`
CreatedAt time.Time // column name is `created_at`
}
// Overriding Column Name
type Animal struct {
AnimalId int64 `gorm:"column:beast_id"` // set column name to `beast_id`
Birthday time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast`
Age int64 `gorm:"column:age_of_the_beast"` // set column name to `age_of_the_beast`
}
- Timestamp를 지정합니다.
- CreatedAt: model을 생성할 때, 타임스탬프를 기록합니다.
- UpdatedAt: model이 update될 때, 타임스탬프를 기록합니다.
- DeletedAt: model을 delete할 때, soft delete로 실제로 db상에서 삭제를 하지 않습니다. 그리고 타임스탬프로 기록합니다.
// Delete record permanently with Unscoped
db.Unscoped().Delete(&order)
//// DELETE FROM orders WHERE id=10;
//실제로 영구적으로 삭제하는 함수는 위와 같습니다.
'개발일지 > go' 카테고리의 다른 글
GORM (3) - Associations (0) | 2020.05.07 |
---|---|
GORM (2) - CRUD (0) | 2020.04.24 |
gRPC - Multiplexing, Metadata, Load Balancing and Compression (0) | 2020.04.13 |
gRPC - Context and Error Handling (0) | 2020.04.11 |
gRPC - Interceptor (0) | 2020.03.31 |