개발/Go

[Gin] GORM 관계 설정 완전 정복 - 1:N, N:1, N:M 예제로 배우기

devhooney 2025. 5. 26. 13:46
728x90

 

Go 언어의 대표적인 ORM인 GORM을 쓰다 보면 꼭 마주치게 되는 기능이 바로 관계 설정(Association)이다.
이번 글에서는 실제 예제와 함께 GORM의 다양한 관계 설정을 정리해보고, 실전에서 어떻게 쓰는지까지 알아보자.

 

 

 

 

📌 목차
관계 설정이란?
1:N (has many & belongs to)
N:M (many to many)
Preload로 관계 데이터 로딩하기
팁 & 실수 방지 포인트
마무리 및 다음 예고

 

 


 

728x90

 

 

1. 관계 설정이란?


관계 설정(Association)은 모델 간의 연결 관계를 표현하는 기능이다.

 

대표적으로 다음과 같은 관계가 있다

- 1:N: 하나의 유저가 여러 개의 게시글을 가질 수 있음
- N:1: 게시글은 하나의 유저에 속함
- N:M: 유저는 여러 역할(Role)을 가질 수 있고, 역할도 여러 유저에게 할당될 수 있음


이러한 관계는 SQL에선 JOIN이나 foreign key로 표현되는데, GORM은 이를 Go 코드로 깔끔하게 처리할 수 있게 해준다.

 

 

 

 

2. 1:N (has many & belongs to)

예제: User ↔ Posts

// models/user.go
type User struct {
	ID    uint
	Name  string
	Posts []Post `gorm:"foreignKey:UserID"`
}

// models/post.go
type Post struct {
	ID     uint
	Title  string
	UserID uint
}

 

설명
- User는 여러 Post를 가짐 (has many)
- Post는 하나의 User에 속함 (belongs to)
- UserID는 Post에서 User의 외래키로 사용됨.

 

 


마이그레이션 예시:

db.AutoMigrate(&User{}, &Post{})

 

 

 

 

 

 

3. N:M (many to many)


예제: User ↔ Role

// models/user.go
type User struct {
	ID    uint
	Name  string
	Roles []Role `gorm:"many2many:user_roles;"`
}

// models/role.go
type Role struct {
	ID   uint
	Name string
}

 

설명
- GORM이 자동으로 user_roles라는 중간 테이블을 생성
- 해당 테이블은 user_id, role_id로 구성됨

 

 


마이그레이션 예시

db.AutoMigrate(&User{}, &Role{})

 

추가 데이터 삽입 예시

admin := Role{Name: "admin"}
user := User{Name: "Jane", Roles: []Role{admin}}

db.Create(&user)

 

 

 

 

4. Preload: 관계된 데이터 한 번에 가져오기


JOIN처럼 관계 모델까지 한 번에 가져오고 싶다면 Preload()를 사용한다.

var users []User
db.Preload("Posts").Find(&users)

 

 

Preload("Posts")는 내부적으로 SQL JOIN처럼 작동하여 유저와 관련된 포스트까지 모두 불러온다.
N:M 관계일 경우도 똑같이 사용 가능하다.

 

db.Preload("Roles").Find(&users)

 

 

 

 

 

5. 실전 팁 & 실수 방지 포인트


- gorm:"foreignKey:UserID"는 명시하지 않아도 GORM이 자동으로 추측하지만, 명확히 지정하는 것이 좋다.
- 중간 테이블 이름(user_roles)은 many2many:user_roles로 설정해야 원하는 이름으로 생성됨
- AutoMigrate()는 필드가 빠진 경우에는 컬럼을 추가하지만 삭제는 하지 않음
- Preload 대신 Lazy Loading을 하려면 .Association()을 사용할 수 있지만 성능 저하에 주의

 

 

 

 

 

마무리


이번 글에서는 GORM의 관계 설정에 대해 가장 핵심적인 부분인 1:N, N:1, N:M 관계를 실전 예제와 함께 살펴봤다.

이 내용을 바탕으로 복잡한 데이터 구조도 깔끔하게 GORM으로 다룰 수 있게 될 것이다.

 

 

 

 

 

 

 

728x90