오늘 배운 내용 중 다대다 관계(N:M)와 중간 테이블에 대해 정리해보았다. JPA에서 두 엔티티가 다대다(N:M) 관계일 때, 이를 효과적으로 처리하기 위해 중간 테이블을 사용해야 한다는 것을 새롭게 알게 되었다.
다대다 관계는 두 엔티티가 서로 여러 개의 관계를 가질 수 있는 상황을 말한다. 예를 들어, 유저(Member)와 일정(Todo) 간의 관계를 생각해보면:
이러한 경우, 다대다 관계를 직접 표현할 수 없기 때문에 중간 테이블을 사용해 이 관계를 처리해야 한다.
중간 테이블은 다대다 관계를 관리하기 위해 두 엔티티의 외래 키를 포함한 테이블이다. 이 테이블은 두 엔티티 사이의 관계를 저장하고 관리한다.
예를 들어, 유저(Member)와 일정(Todo) 간의 다대다 관계를 처리하기 위해 중간 테이블인 user_todo
테이블을 생성하여, 유저와 일정 간의 연결을 저장한다.
CREATE TABLE user_todo
(
user_id BIGINT NOT NULL, -- 유저 테이블(member)의 외래키
todo_id BIGINT NOT NULL, -- 일정 테이블(todo)의 외래키
PRIMARY KEY (user_id, todo_id), -- 두 필드를 복합 기본키로 설정하여 중복을 방지
FOREIGN KEY (user_id) REFERENCES member (id), -- 유저와 연결된 외래키
FOREIGN KEY (todo_id) REFERENCES todo (id) -- 일정과 연결된 외래키
);
JPA에서는 @ManyToMany
어노테이션을 사용하여 두 엔티티 간의 다대다 관계를 설정할 수 있다. 이때, 중간 테이블은 @JoinTable
어노테이션을 사용해 지정한다.
Todo
엔티티에서의 설정:@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "user_todo", // 중간 테이블 이름
joinColumns = @JoinColumn(name = "todo_id"), // Todo 엔티티의 외래 키
inverseJoinColumns = @JoinColumn(name = "user_id") // Member 엔티티의 외래 키
)
private List<Member> members; // 여러 유저가 여러 일정을 담당
Member
엔티티에서의 설정:@ManyToMany(mappedBy = "members", fetch = FetchType.LAZY)
private List<Todo> todos; // 여러 유저가 여러 일정을 담당
위와 같이 설정하면, JPA는 자동으로 다대다 관계를 위한 중간 테이블인 user_todo
를 생성하고 관리한다. 이 테이블은 각 유저가 어떤 일정을 담당하는지 정보를 저장한다.
중간 테이블은 다대다 관계에서 다음과 같은 역할을 수행한다:
user_id
와 todo_id
)를 복합 기본 키로 설정해, 동일한 유저와 동일한 일정에 대한 중복 등록을 방지한다.@ManyToMany
와 @JoinTable
어노테이션을 사용하여 JPA에서 중간 테이블을 쉽게 설정할 수 있다.다대다 관계는 실제 프로젝트에서도 자주 발생할 수 있는 상황이기 때문에 이를 잘 관리하는 것이 중요하다. JPA에서 중간 테이블을 사용하여 다대다 관계를 관리하는 방식을 이해하는 것은 매우 유용하며, 이를 통해 더 복잡한 엔티티 관계를 쉽게 처리할 수 있다.