JPA에서 다양한 연관관계 매핑은 객체 모델에서의 관계와 데이터베이스의 테이블 간 관계를 정의하고 관리하는 중요한 부분이다. 객체 지향 세계에서 엔티티는 다양한 방식으로 서로 연관될 수 있다. JPA는 이러한 연관관계를 다양한 매핑 방식으로 처리하며, 이를 통해 관계형 데이터베이스의 외래 키와 객체 참조 간의 불일치를 해결한다.
연관관계는 크게 네 가지로 분류할 수 있다:
- 다대일(Many-to-One)
- 일대다(One-to-Many)
- 일대일(One-to-One)
- 다대다(Many-to-Many)
1. 다대일(Many-to-One) 관계
다대일 관계는 가장 일반적으로 사용되는 관계로, 여러 엔티티가 하나의 엔티티와 연결되는 관계이다. 예를 들어, 여러 명의 회원이 하나의 팀에 속하는 경우를 다대일 관계라고 한다.
예시: 여러 명의 회원 -> 하나의 팀 (다대일 관계)
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "team_id") // 외래 키 매핑
private Team team;
private String name;
// getter, setter...
}
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
// getter, setter...
}
설명
- @ManyToOne: 여러 Member가 하나의 Team에 속하는 다대일(Many-to-One) 관계이다.
- @JoinColumn: 데이터베이스의 외래 키(team_id)를 통해 관계를 매핑한다. 이는 Member 엔티티에서 team_id라는 컬럼을 생성하고, Team 엔티티와의 관계를 관리한다.
다대일 관계의 특징
- 외래 키는 다 쪽(Many)에 존재한다. 즉, Member 엔티티가 외래 키를 가지며, team_id 컬럼을 통해 관계를 맺는다.
- 가장 많이 사용되는 연관관계이며, 객체지향과 데이터베이스 모두에서 쉽게 이해할 수 있는 관계이다.
2. 일대다(One-to-Many) 관계
일대다 관계는 하나의 엔티티가 여러 엔티티와 연관되는 관계이다. 즉, 반대 방향에서 바라본 다대일 관계라고 볼 수 있다. 예를 들어, 하나의 팀에 여러 명의 회원이 속하는 경우를 일대다 관계라고 한다.
예시: 하나의 팀 -> 여러 명의 회원 (일대다 관계)
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team") // 양방향 연관관계 설정
private List<Member> members = new ArrayList<>();
// getter, setter...
}
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "team_id") // 외래 키 설정
private Team team;
private String name;
// getter, setter...
}
설명
- @OneToMany(mappedBy = "team"): 일대다 관계에서 Team이 여러 Member와 연관된다. mappedBy 속성은 연관관계의 주인이 아님을 나타낸다.
- 양방향 연관관계에서 일대다 관계는 ManyToOne 관계와 함께 사용되며, Member 엔티티가 연관관계의 주인이 된다.
일대다 관계의 특징
- 일대다 관계에서는 다 쪽(Many)이 외래 키를 관리한다. 즉, 외래 키는 Member 엔티티에 존재한다.
- 일대다 단방향 관계는 거의 사용되지 않으며, 보통 양방향 관계로 설정하는 것이 일반적이다.
- 일대다 단방향 매핑에서는 JPA가 추가적으로 조인 테이블을 생성해야 하므로 성능 이슈가 있을 수 있다. 따라서 다대일 양방향 매핑으로 구현하는 것이 좋다.
3. 일대일(One-to-One) 관계
일대일 관계는 하나의 엔티티가 하나의 엔티티와만 연관되는 관계이다. 예를 들어, 회원과 회원 상세 정보는 1:1 관계일 수 있다. 하나의 회원은 하나의 회원 상세 정보만을 가지며, 그 반대도 성립한다.
예시: 회원 -> 회원 상세 정보 (일대일 관계)
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String name;
@OneToOne
@JoinColumn(name = "detail_id") // 외래 키 매핑
private MemberDetail memberDetail;
// getter, setter...
}
@Entity
public class MemberDetail {
@Id @GeneratedValue
private Long id;
private String address;
private String phone;
// getter, setter...
}
설명
- @OneToOne: 일대일(One-to-One) 관계를 나타낸다. Member는 MemberDetail과 일대일 관계를 가진다.
- @JoinColumn: 외래 키를 통해 두 엔티티를 매핑한다. 외래 키는 보통 둘 중 한쪽에만 존재하며, 외래 키를 가지는 쪽이 연관관계의 주인이 된다.
일대일 관계의 특징
- 외래 키는 둘 중 하나에 존재하며, 보통 더 많이 조회되는 쪽이 연관관계의 주인이 된다.
- 일대일 관계는 외래 키를 어디에 두느냐에 따라 다르게 설정할 수 있다.
- Member가 주인인 경우: @JoinColumn을 사용하여 Member 엔티티가 외래 키를 가진다.
- MemberDetail이 주인인 경우: 외래 키를 MemberDetail 엔티티에 둘 수 있다.
- 일대일 관계에서는 연관관계를 주의 깊게 설정해야 성능 최적화를 할 수 있다.
4. 다대다(Many-to-Many) 관계
다대다 관계는 여러 엔티티가 여러 엔티티와 연관되는 관계이다. 예를 들어, 여러 명의 학생이 여러 강의를 수강할 수 있고, 각 강의는 여러 학생이 들을 수 있는 경우를 다대다 관계라고 한다. 다대다 관계는 관계형 데이터베이스에서 N 관계로 표현되며, 중간에 연결 테이블을 통해 관리된다. JPA에서는 다대다 관계를 직접 사용할 수 있지만, 성능 및 복잡성 문제 때문에 중간 테이블을 명시적으로 관리하는 것이 좋다.
예시: 학생 <-> 강의 (다대다 관계)
@Entity
public class Student {
@Id @GeneratedValue
private Long id;
private String name;
@ManyToMany
@JoinTable(name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id"))
private List<Course> courses = new ArrayList<>();
// getter, setter...
}
@Entity
public class Course {
@Id @GeneratedValue
private Long id;
private String name;
@ManyToMany(mappedBy = "courses")
private List<Student> students = new ArrayList<>();
// getter, setter...
}
설명
- @ManyToMany: 다대다(Many-to-Many) 관계를 정의한다. 여기서 Student와 Course가 다대다 관계를 가진다.
- @JoinTable: 다대다 관계에서는 중간 테이블이 필요하다. @JoinTable을 통해 student_course라는 연결 테이블을 생성하고, 외래 키를 정의한다.
- joinColumns: Student의 외래 키
- inverseJoinColumns: Course의 외래 키
다대다 관계의 특징
- 관계형 데이터베이스에서는 다대다 관계를 직접 사용할 수 없으며, 중간 테이블을 통해 다대다 관계를 관리해야 한다.
- JPA는 자동으로 중간 테이블을 생성해 주지만, 중간 테이블에 추가적인 데이터를 저장해야 하거나, 더 복잡한 관리가 필요한 경우에는 다대다 관계를 일대다, 다대일 관계로 풀어내는 것이 좋다.
- 예를 들어, 학생-강의 관계를 다대다에서 학생-수강 테이블(일대다), 수강 테이블-강의(다대일)로 풀어서 설계하는 방식이 더 유연하다.
- 다대일(Many-to-One): 가장 일반적인 관계로, 여러 엔티티가 하나의 엔티티와 연관된다. 외래 키는 다쪽(Many)에 있다.
- 일대다(One-to-Many): 하나의 엔티티가 여러 엔티티와 연관된다. 보통 다대일 관계와 함께 양방향 관계로 설정하며, 외래 키는 Many 쪽에서 관리한다.
- 일대일(One-to-One): 하나의 엔티티가 하나의 엔티티와만 연관된다. 외래 키는 더 자주 조회되는 쪽이 주로 관리하며, 성능을 고려한 설계가 필요한다.
- 다대다(Many-to-Many): 여러 엔티티가 여러 엔티티와 연관된다. 중간 테이블을 통해 관리되며, 복잡한 상황에서는 중간 테이블을 명시적으로 관리하는 설계가 더 좋다.
'Backend study > JPA' 카테고리의 다른 글
프록시와 연관관계 관리 (0) | 2024.10.30 |
---|---|
고급 매핑 (0) | 2024.10.29 |
연관관계 매핑 기초 (1) | 2024.10.22 |
엔티티 매핑(Entity Mapping) (1) | 2024.10.21 |
영속성 관리 (0) | 2024.10.17 |