Be ready to study forever - 개발자 꿈나무
[JPA] 다양한 연관관계 매핑-2 본문
연관관계를 매핑할 때 고려해야할 것 3가지는:
- 다중성(1:N, N:1, 1:1, N:M)
- 단방향, 양방향
- 연관관계 주인
인데, 조합을 따져보면
N:1 단방향 (@ManyToOne)
N:1 양방향 (@ManyToOne<-> @OneToMany)
1:N 단방향 (@OneToMany)
1:N 양방향 (@OneToMany <-> @ManyToOne)
1:1 양방향 (@OneToOne <-> @OneToOne)
N:M 양방향 (@ManyToMany <-> @ManyToMany)
정도의 관계가 나올 수 있다. 관계가 나올 수 있는 조합이 많아서 특징별로 다 외워야 하나… 라고 생각 할 수도 있지만, 몇 가지 주의할 만한 관계를 제외하고는 원칙은 같다. 연관관계의 주인은 @ManyToOne쪽이 가져 가는게 맞다고. 그리고 설계시에 가능한한 단방향에서 끝낼 수 있으면 구지 양방향으로 연결 하지 않는 게 좋고, 나중에 양방향이 필요하다면 반대쪽에 어노테이션만 달아주면 된다. 이유는 양방향으로 가져가면 어쩔 수 없이 생기는 리스크(사람의 실수) 예를들면 mappedBy 필드에다 업데이트를 하는 경우(DB에 반영 안됨…) 가 생기기 때문에.
연관관계 주의점)
1:N 단방향 (@OneToMany)은 단방향이기 때문에 One쪽에서 외래키를 관리하게 된다.
그림과 같이 Team 객체에서 Member의 외래키를 관리하게 되면 직관적이지 않고 예상치 못한 쿼리가 나갈 수 있기 때문에 이러한 경우에는 1:N 단방향 (@OneToMany)보다 1:N 양방향 (@OneToMany <-> @ManyToOne)으로 설계 전략을 가져가는 좋다.
1:1 양방향 (@OneToOne <-> @OneToOne)
1:1은 JPA에서는 단방향을 지원하지 않고 있다. 그리고 DB에서의 설계는 외래키에 unique constraint를 걸게 되면 1개의 엔티티에 1개의 유니크한 외래키 밖에 들어올 수 없으므로 1:1 관계가 된다. 그럼, 1:1 양방향 (@OneToOne <-> @OneToOne)도 @ManyToOne쪽은 없지만 외래키가 있는 쪽이 연관관계 주인이 되는 것이 바람직 하다. 그럼 어디에 외래키를 심는게 좋을까? 는 사실 생각이 좀 필요한 문제이다. 장단점을 비교해 보자면,
주 테이블에 외래 키
- 주 객체가 대상 객체의 참조를 가지는 것 처럼 주 테이블에 외래 키를 두고 대상 테이블을 찾음
- 객체지향 개발자 선호
- JPA 매핑 편리
- 장점: 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인 가능
- 단점: 값이 없으면 외래 키에 null 허용
대상 테이블에 외래 키
- 대상 테이블에 외래 키가 존재
- 전통적인 데이터베이스 개발자 선호
- 장점: 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조 유지
- 단점: 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨(프록시는 뒤에서 설명)
N:M 양방향 (@ManyToMany <-> @ManyToMany)
다대다 양방향 매핑은 아주 편리해 보이지만 실무에서는 쓰이지 않는다.
@ManyToMany로 어노테이션을 걸게 되면 조인 테이블에 추가적으로 값을 넣을 수 없기 때문이다. 사실은 하다못해 createdAt, lastUpdatedAt 정도라도 들어가야 하는데 넣을 수가 없다 ㅠㅠ.
따라서 실무에서는 직접 조인트 테이블을 만들어서 사용한다.
관계 매핑 어노테이션의 속성)
@JoinColumn
@ManyToOne
@OneToMany
요약하자면…
1. 단방향 매핑으로 끝낼 수 있으면 단방향 매핑으로 끝내는게 좋다,
2. 연관관계 주인은 @ManyToOne에서 가져 가는게 바람직하다.
3. 1:N (@OneToMany) 단반향 관계보다 양방향으로 설계 하는게 바람직하다.(@ManyToOne에 연관관계 주인을 설정하기 위해서)
4. 1:1(@OneToOne)관계는 단방향 X, 외래키가 있는 쪽이 연관관계 주인을 가져가고, 외래키는 전략에 따라 놓는다.
5. @ManyToMany 관계는 조인트 테이블에 추가적으로 관계를 심을 수 없기 때문에 사용하지 말고 @OneToMany -> @ManyToOne, @ManyToOne <- @OneToMany 직접 조인트 테이블을 만들어 사용해라.
'Programming > JPA' 카테고리의 다른 글
[JPA] 엔티티매핑 (0) | 2021.01.24 |
---|---|
[JPA] 고급 매핑 - 3 (0) | 2021.01.23 |
[JPA] 연관관계 매핑 기초 - 1 (0) | 2021.01.23 |
[JPA] 영속성 컨텍스트란? (0) | 2021.01.23 |
[JPA]실행하기 (0) | 2021.01.22 |