연관관계 매핑시 고려사항 3가지
1. 다중성
2. 단방향, 양방향
3. 연관관계의 주인
- 객체 양방향 관계는 참조가 2군데 있기 때문에 둘중 테이블의 외래 키를 관리할 곳을 지정해야함
- 외래 키를 관리하는 참조
- 주인의 반대편 : 외래 키에 영향을 주지 않음, 단순 조회
다대일[N:1]
가장 많이 사용함
단반향
아래와 같이 [N]에서 외래 키를 관리하고 Team을 조회 하고 추가할 수 있다. Team에 서는 조회하지 못함 -> Team에서 Member을 조회하는일이 빈번하다고 하면 -> 양반향 으로 매핑해주는게 좋음.
양반향
단반향에서 TEAM이 MEMBER를 mapped by 를 추가하여 MEMBER를 조회할 수 있다. (읽기 전용)
일대다[1:N]
1이 연관관계의 주인이다.
단방향
TEAM 에서 외래키를 관리하게 되면 TEAM에 MEMBER를 추가할 때 MEMBER 또한 update를 한다 성능상 추천 하지 않고 실제 사용할 때 쿼리추적시 update문을 보고 의문을 가질 수 있다.(실무에서 수많은 테이블이 있을 때 좋지 않음)
왜 Team 은 MEMBER의 외래키를 관리하게 될까?
테이블 연관관계를 생각해보면 TEAM 에서 MEMBER을 추가할 때마다 TEAM 로우 또한 생성되어야 한다. -> 잘못된 설계
이기 때문에 MEMBER 테이블의 외래키를 관리하게 되는 것
사용법 Team.java 에 아래와 같이 코드를 추가한다. 단방향이므로 MEMBER에는 아무것도 추가하지 않는다.
@OneToMany
@JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<>();
일대다 단방향 매핑보다는 다대일 양방향 매핑을 사용하자
- 엔티티가 관리하는 외래 키가 다른 테이블에 있음
- 연관관계 관리를 위해 추가로 UPDATE SQL 실행
양반향
공식적으로 존재하지 않음.
@JoinColumn(insert=false,updateable=false) -> 읽기 전용 필드를 사용해서 양방향 처럼 사용하는 방법
다대일 양방향을 사용하자
@ManyToOne 에서는 왜 mappedBy가 없을까?
연관관계의 주인이 다른 테이블의 외래 키를 관리하기 때문에 야매 매핑을 사용해야 하는데 공식스팩에서 오히려 혼란을 줄 수 있기 때문에 없다!
일대일[1:1]
일대일 관계 반대도 일대일
- 주 테이블이나 대상 테이블 중에 외래 키 선택 가능
- 외래 키에 데이터베이스 유니크 제약조건 추가 되어야 함
- 값이 없으면 외래 키에 null 허용이 된다.
- 주 테이블만 조호회해도 대상 테이블에 데이터가 있는지 확인 가능하다.
- 다대일 연관관계랑 유사
코드는 아래와 같이 사용한다. LOKCER에 MEMBER을 넣어도 된다. (선택가능)
@OneToOne
@JoinColumn(name= "LOCKER_ID")
private Locker locker;
양반향
다대일 양방향 매핑 처럼 외래 키가 있는 곳이 연관관계의 주인이다. 반대편은 아래와 같이 mappedBy 적용
@OneToOne
@JoinColumn(name= "LOCKER_ID")
private Locker locker;
/////////////////////////////////////////
@OneToOne(mappedBy="locker")
private Member member;
대상 테이블에 외래 키가 있는 단방향일 경우? 지원하지 않음 하지만 양반향은 지원한다.
대상 테이블에 외래 키가 존재하는 경우이고 전통적인 DB 개발자가 선호한다.
양반향일 경우 아래와 같이 자신의 Entity에 있는 외래키는 자신이 직접 관리 해야 한다.
다대다[N:N]
실무에서 쓰면 안된다! -> 다대다로 풀리는 간단한게 없다.
관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다.
연결 테이블을 추가해서 일대다, 다대일 관계로 풀어내야 한다.
편리해보이지만 연결만 하고 끝나지 않는다. 중간테이블에 다른 정보를 넣을 수 없다.
- @ManyToMany 사용
- @JoinTable로 연결 테이블 지정
- 다대다 매핑 : 단방향, 양방향 가능
아래와 같이 중간테이블을 지정해주면 MEMBER와 PRODUCT 테이블에 PK를 갖고 있는 테이블이 생성된다.
@ManyToMany
@joinTable(name="MEMBER_PRODUCT")
private List<Product> products = new ArrayList<>();
// 양반향일 경우
@ManyToMany(mappedBy="products")
private List<Member> members = new ArrayList<>();
'WEB > JPA' 카테고리의 다른 글
7. 자바 ORM 표준 JPA 프로그래밍 - 프록시와 연관관계 관리 (0) | 2021.05.18 |
---|---|
6. 자바 ORM 표준 JPA 프로그래밍 - 고급매핑 (0) | 2021.05.17 |
4. 자바 ORM 표준 JPA 프로그래밍 - 연관관계 (0) | 2021.05.14 |
3. 자바 ORM 표준 JPA 프로그래밍 - 엔티티 매핑 (0) | 2021.05.13 |
2. 자바 ORM 표준 JPA 프로그래밍 - 내부 동작 방식 (0) | 2021.05.13 |