연관관계 매핑시 고려사항 3가지

1. 다중성

다대일 [N:1] @ManyToOne

일대다 [1:N] @OneToMany

일대일 [1:1] @OneToOne

다대다 [N:M] @ManyToMany  (실무에선 거의 쓰면안된다.)

 

2.단방향,양방향

테이블: 외래키 하나로 양쪽 조인가능

객체: 참조용 필드가 있는쪽만 참조 가능. 그래서 단방향이므로 양쪽으로 서로 참조하려면 두개의 단방향으로 보면된다. 

 

3.연관관계 주인

주인은 외래키의 정보를 관리한다.

주인이 아닌곳은 외래키 영향 주지않고 읽기만 가능.

 

이제 다중성에서 연관관계 종류에대해 알아보겠습니다.

 

다대일[N:1]

 단방향 / 양방향 

N:1 단방향일떄 

DB설계시 다(N) 쪽에 외래키를 만들어두게 설계를 해야한다. 

외래키있는곳을 기준으로 객체도 Team을 참조하게 만들어두자.

 

N:1 양방향일떄

객체에서 추가만하면되지 DB에는 변화가 있을필요없다.

 

 

일대다[1:N]

단방향 / 양방향

 

1:N 단방향일떄

위에 모델(그림)은 실무에서 사용하기에 좋은 설계는 아니다.

팀은 맴버들이 누군지 알수있는데 맴버는 어느팀인지 모르는 상황이다. 

이떄 Team에 members의 값을 바꾸면 DB 에 Member 테이블에서 Team_Id의 값을 바꿔줘야한다.

 

객체와 테이블 차이떄문에 반대편 테이블의 외래키를 관리하는 헷갈리는 구조가 되어버린다.

@OneToMay를 쓸떄는 @JoinColum을 꼭 써줘야한다.

 

1:N 양방향일떄

이런 매핑은 공식적으로 존재 안하며

@JoinColumn(insertable=false, updateable= false)를 추가해줘야한다. 

읽기전용필드를 사용해서 양방향처럼 사용하는 방법이다. 

웬만하면 N:1 양방향을 사용하자!!

 

일대일[1:1]

외래키에 DB 유니크 제약조건 추가

 

단방향 / 양방향

N:1 단방향과 유사한데

외래키가 있는곳을 연관관계 주인으로 두고

양방향으로 만들거면 주인 아닌곳에 mappedBy 적용.

 

주 테이블(Member)이나 대상 테이블(Locker)중에 외래키를 아무곳이나 넣어도된다.

그래도 각각의 차이가 있다면

주 테이블에 외래키

객체지향 개발자가 선호하며 JPA 매핑이 편리하다.

장점: 주 테이블만 조회해도 대상테이블에 데이터 있는지 확인가능

단점: 값없으면 외래키에 null 허용.

 

대상 테이블에 외래키

전통적인 DB 개발자 선호

장점: 주테이블-대상테이블 [1:1] -> 1:N 변경시 테이블 구조 유지가능

단점:

1. 프록시 기능 한계로 지연로딩으로 설정해도 항상 즉시로딩됨.(이게더 치명적인 단점)

2. 양방향으로 만들어야 되는것!

 

 

다대다[N:M]

관계형 DB는 정규화된 테이블 2개로 N:M 관계를 표현할수없다.

연결 테이블을 추가해서 1:N, N:1로 풀어내야함.

 

 

객체는 컬렉션을 사용해서 객체 2개로 다대다 관계가 가능하다.

 

@JoinTable로 연결테이블 지정

@ManyToMany
@JoinTable(name = "MEMBER_PRODUCT")
private List<Product> products = new ArrayList<>();

 

N:M의 한계

 

실무에서 사용못하는게 연결테이블이 연결만 하고 끝나지않음.

연결테이블(Member_Product)에 주문시간,수량같은 데이터가 추가로 들어올수있다. 

 
 
 
 
 

 

 

N:M 한계 해결방안

연결 테이블용 엔티티를 추가(연결테이블을 엔티티로 승격)

@ManyToMany -> @OneToMany, @ManyToOne

 

실전에서 @ManyToMany를 사용못한다고 생각해라!!

 
 
 

'𝗦𝗣𝗥𝗜𝗡𝗚 > 𝐎𝗥𝗠-𝗝𝗣𝐀' 카테고리의 다른 글

고급 매핑  (1) 2024.01.03
연관관계 매핑 기초  (0) 2024.01.03
엔티티 매핑  (0) 2024.01.02
JPA 영속성 컨텍스트  (0) 2023.12.27
JPA 구동방식  (0) 2023.12.27