Go 언어의 대표적인 ORM인 GORM을 쓰다 보면 꼭 마주치게 되는 기능이 바로 관계 설정(Association)이다.
이번 글에서는 실제 예제와 함께 GORM의 다양한 관계 설정을 정리해보고, 실전에서 어떻게 쓰는지까지 알아보자.
📌 목차
관계 설정이란?
1:N (has many & belongs to)
N:M (many to many)
Preload로 관계 데이터 로딩하기
팁 & 실수 방지 포인트
마무리 및 다음 예고
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으로 다룰 수 있게 될 것이다.
'개발 > Go' 카테고리의 다른 글
[Gin] GORM 성능 최적화 팁 - Preload, Select, Index 전략까지! (64) | 2025.06.04 |
---|---|
[Gin] GORM 고급 기능 완전 정복 - Soft Delete, Hook, 트랜잭션까지! (99) | 2025.05.28 |
[Gin] Go + Gin + GORM으로 백엔드 만들기 (기초부터 CRUD까지) (41) | 2025.05.24 |
[Gin] Gin 시작해보자! (95) | 2025.05.14 |
[Fiber] Fiber Template 사용하기 (2) | 2022.11.08 |