본문 바로가기

개발일지/go

GORM (1) - Getting Started

이번 포스팅에서는 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