![[Spring] JPA 연관관계 매핑 알아보기](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFFScZ%2Fbtr0zFBeeOn%2FEkQtNr9XnEWn3RaiRLhPZ1%2Fimg.png)
연관관계를 매핑할 때는 다음 3가지를 고려해야 합니다.
- 방향: 단방향, 양방향
- 다중성: 일대일(1:1), 일대다(1:N), 다대일(N:1), 다대다(N:M)
- 연관관계의 주인: 양방향일 때, 연관관계의 주인으로 외래 키를 가짐
다대일(N:1) 관계
데이터 모델링에서는 관계를 맺어주면 자동으로 양방향 관계가 되어 서로를 참조합니다. 하지만 객체지향 모델링에서는 구현하려는 서비스에 따라 단방향 관계인지, 양방향 관계인지 선택을 해야 합니다.
@Entity
public class Student {
@Id @GeneratedValue
@Column(name = "student_id")
private Long id; //PK
private String studentName;
private Long school_id; //FK
}
학교와 학생 DB 테이블을 작성한다고 하면 학생:학교(N:1)이므로 학생 테이블에 외래 키(FK)를 둬야 합니다.
이 경우, 학생이 속한 학교에 대한 정보를 조회하려면 학생을 먼저 조회한 뒤 외래 키인 school_id를 통해서 학교를 조회해야 합니다. 연관관계가 많아지면 과정이 그만큼 복잡해집니다.
그렇기에 객체는 참조(주소)로 연관관계를 맺습니다.
@Entity
public class Student {
@Id @GeneratedValue
@Column(name = "student_id")
private Long id;
private String studentName;
@ManyToOne
@JoinColumn(name = "school_id")
private School school;
}
@Entity
public class School {
@Id @GeneratedValue
@Column(name = "school_id")
private Long id;
private String schoolName;
@OneToMany(mappedBy = "school")
private List<Student> students = new ArrayList<>();
}
- @Entity: JPA를 사용해서 DB 테이블과 매핑할 클래스는 @Entity를 붙여야 합니다.
- @Id: JPA 엔티티 객체의 기본 키(PK)를 지정합니다.
- @GeneratedValue: 기본 키(PK) 값에 대한 생성 전략을 제공합니다.
- @Column: 객체 필드를 테이블 칼럼에 매핑합니다.
- @JoinColumn: 외래 키(FK)를 매핑할 때 사용합니다. name 속성에 매핑할 외래 키 칼럼명을 지정합니다.
일대일(1:1) 관계
다음은 1:1 관계입니다. 예시로 개인 과외를 생각해 보면, 선생님과 학생은 1:1 관계입니다. 코드로 보면 아래와 같습니다.
@Entity
public class Teacher {
@Id @GeneratedValue
@Column(name = "teacher_id")
private Long id;
private String name;
@OneToOne(mappedBy = "teacher")
private Student student;
}
@Entity
public class Student {
@Id @GeneratedValue
@Column(name = "student_id")
private Long id;
private String name;
@OneToOne
@JoinColumn(name = "teacher_id")
private Teacher teacher;
}
다대다(N:M) 관계
다대다(N:M) 관계의 경우 실무에서는 사용하지 않습니다. 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없습니다. 그렇기에 중간 테이블(조인 테이블)을 추가해서 일대다, 다대일 관계로 풀어내야 합니다.
아래는 김영한 님의 다대다 관계 예시입니다. 상품과 카테고리의 경우 하나의 카테고리는 여러 상품을 가질 수 있고 반대로 상품 또한 여러 카테고리에 소속될 수 있기에 다대다 관계로 설정하였습니다.
@Entity
public class Category {
@Id @GeneratedValue
@Column(name = "category_id")
private Long id;
private String name;
@ManyToMany
@JoinTable(name = "category_item",
joinColumns = @JoinColumn(name = "category_id"),
inverseJoinColumns = @JoinColumn(name = "item_id"))
private List<Item> items = new ArrayList<>();
}
@Entity
public class Item {
@Id @GeneratedValue
@Column(name = "item_id")
private Long id;
private String name;
private int price;
private int stockQuantity;
@ManyToMany(mappedBy = "items")
private List<Category> categories = new ArrayList<>();
}
위에서 말했다시피 다대다 관계의 경우 위와 같이 @ManyToMany는 실무에서는 사용하지 않습니다. 대신 중간 테이블을 만들어 일대다, 다대일 관계로 풀어서 작성하여야 합니다.
'Spring' 카테고리의 다른 글
[Spring] Cascade옵션 알아보기 (0) | 2023.03.15 |
---|---|
[Spring] Bean Validation 알아보기 (1) | 2023.03.09 |
[Spring] DTO를 사용하는 이유를 알아보자 (0) | 2023.03.04 |
[Spring] 의존성 주입(DI) 알아보기 (0) | 2023.02.28 |
[Spring] 프로젝트 생성 및 환경 세팅 (0) | 2023.02.22 |
느리더라도 단단하게 성장하고자 합니다!
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!