연관관계 매핑이란?
객체지향에서는 객체와 객체가 서로를 참조하지만, 데이터베이스에서는 객체가 아닌 외래키(Foreign Key) 로 관계를 표현한다.
JPA 연관관계 매핑은 객체의 참조를 데이터베이스의 외래키와 연결해주는 기능이다.
예를 들어 회원과 주문이 있다고 가정하면,
- 회원 1명은 여러 개의 주문을 할 수 있다.
- 주문 1개는 회원 1명에게만 속한다.
데이터베이스에서는 다음과 같이 표현된다.
Member
----------------
id
name
Order
----------------
id
price
member_id (FK)
하지만 객체에서는 숫자(member_id)를 저장하지 않고 객체를 저장한다.
@ManyToOne
@JoinColumn(name = "member_id")
private Member member;
즉, 객체는 Member 객체를 참조하고, JPA가 이를 member_id 외래키로 자동 변환해준다.
@ManyToOne
"여러 개(N)의 객체가 하나(1)의 객체를 참조한다."
회원 1명
│
├─ 주문1
├─ 주문2
└─ 주문3
주문(Order) 입장에서 보면
주문(N)
↓
회원(1)
이므로 Order 엔티티에는 이렇게 쓴다.
@ManyToOne
@JoinColumn(name = "member_id")
private Member member;
@OneToMany
회원 입장에서 보면
회원(1)
↓
주문(N)
이므로 Member 엔티티에는 이렇다.
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<>();
왜 @ManyToOne이 연관관계의 주인일까?
JPA에서는 외래키(FK)를 가진 엔티티를 연관관계의 주인으로 정한다.
Order
member_id
외래키는 Order 테이블에 존재한다.
Order
↓
member_id
를 수정해야 실제 데이터베이스가 변경된다.
그래서 @ManyToOne이 연관관계의 주인이 된다.
@ManyToOne
@JoinColumn(name = "member_id")
@OneToMany(mappedBy = "member")
반대로 @OneToMany는 읽기 전용(주인이 아님) 역할을 한다.
@JoinColumn이란?
외래키(FK) 컬럼을 생성하는 어노테이션이다.
@JoinColumn(name = "member_id")
라고 작성하면
DB에는
member_id
라는 외래키 컬럼이 생성된다.
FetchType
연관된 데이터를 언제 조회할 것인지 결정하는 전략이다.
EAGER (즉시 로딩)
객체를 조회하는 순간 연관 객체까지 함께 조회한다.
Movie
↓
Review
Review
Review
필요하지 않은 데이터까지 가져올 수 있으므로 성능에 영향을 줄 수 있다.
LAZY (지연 로딩)
객체를 먼저 조회하고,
연관 객체는 실제 사용할 때 조회한다.
Movie
↓
(Proxy 객체)
나중에
movie.getReviews();
를 호출하는 순간
DB에서 Review를 조회한다.
실무에서는 대부분 LAZY를 기본으로 사용한다.
Proxy란?
실제 객체 대신 먼저 생성되는 가짜 객체이다.
LAZY 전략에서는 실제 객체 대신 Proxy 객체를 반환한다.
예를 들어
Order order = orderRepository.findById(1L).get();
처음에는
Order
↓
Proxy(Member)
만 존재한다.
이후
order.getMember().getName();
를 호출하면 그 순간 DB에서 Member를 조회하여 실제 객체를 가져온다.
Proxy
↓
실제 객체
'Spring' 카테고리의 다른 글
| Spring 커스텀 예외 만들기와 전역 예외 처리 (0) | 2026.08.04 |
|---|---|
| [Spring] Session과 JWT란? (0) | 2026.07.03 |
| [Spring] 핵심 개념 정리 (Bean, IoC, DI) (0) | 2026.07.02 |
| [Spring] Request DTO는 스프링이 만들어주는데, Response DTO는 왜 내가 만들어야 할까? (0) | 2026.07.01 |
| [Spring 입문] 스프링 전체 흐름 정리 (0) | 2026.06.29 |