연관관계
객체 연관관계와 DB 연관관계를 어떻게 매핑할지를 고민
- 이를 통해 객체지향과 DB사이의 패러다임 불일치 해결
필요한 이유?
- 객체지향적으로 설계하기 위해
테이블에 맞춰 데이터중심으로 모델링하는 경우
- 객체 관점, DB 관점 존재
- DB관점에서는 외래키 하나로 양쪽 테이블을 조인한다. 따라서 나눌 필요 X
- DB관점은 방향성이 없고 객체 관점은 방향성이 있다.
단방향 연관관계
- 한 객체만 참조용 field를 갖는다.
- 객체와 테이블의 연관관계
- 참조를 사용하는 객체 연관관계는 단방향
- FK를 사용하는 테이블 연관관계는 양방향
@ManyToOne
: N : 1 관계라는 매핑 정보.- 다대일 관계에서 항상 “다” 쪽이 외래키를 가진다.
@JoinColumn
: 외래 키 매핑할 때 사용- 이 annotation을 통해 연관관계 맵핑
양방향 연관관계
두 객체 모두 참조용 field를 갖는다.
- 단, 테이블에서는 한쪽 테이블만(다대일에서 다) FK 하나만 가진다.
단순히 단방향보다 조회를 편하게 하기 위한 용도
- 어차피 조회할 수 있는 기능만 있다.(주인 개념때문에)
주인: 연관 관계에서의 FK를 관리하는 주체(주인만이 FK 변경 가능)
비즈니스(도메인)적으로 중요하지 않다.
주인은 테이블 등록, 수정, 삭제 등 제어의 권한 있음
주인이 아니면 read only(DB관점)
- 객체 관점에서는 수정같은게 있을 때 둘다 수정해 데이터 동기화를 해줘야 한다.
외래 키가 있는 곳을 주인으로 설정
다대일 관계에서 다가 갖고있는 일의 외래키부분이 연관관계 주인.
- 이렇게 해야 성능 이슈가 없다.
주인이 아닌쪽은 읽기만 가능
e.g. 1) Member에 Team값을 업데이트 하면 mappedBy로 매핑된 Team의 members로 업데이트 된 DB의 멤버들을 읽을 수 있다는 이야기이다.
e.g. 2)Member에 Team 정보 update 했는데, Team에서 getMembers로 가져왔는데 반영 안됐네? -> 연관관계 설정 안했구나.. 라고 바로 알 수 있다.
출처: https://ict-nroo.tistory.com/122 [개발자의 기록습관]
이걸 많이쓰면 복잡해질 수 있음
- 객체 관점에서는 양쪽 객체 모두에게 참조를 설정해줘야 한다.
- 여기서 실수가 나면 양방향이 깨지는 관계가 존재하게 됨.
- 모두 양방향으로 설정하게 되면 User같은 엔티티는 아주 많은 테이블과 연관 관계를 맺게 됨.
@OneToMany(mappedBy = " ")
를 통해 연관관계 매핑- 주인은 mappedBy 속성 사용 x @JoinColumn 사용
- 주인이 아니면 mappedBy로 주인(필드) 지정
좋은 것은 일단 단방향 매핑으로 하고 나중에 역방향 객체 탐색이 꼭 필요할 때 추가해주기
다대다 연관관계
- n:m 테이블 보다는 연결 테이블을 설정해 관리해야함
- RDBMS에서는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없기 때문
- 한계: 개발 과정에서 추가 데이터가 필요할 수 있으나, 맵핑 정보 외에 추가 정보를 넣는 것이 불가능
- 연결 테이블을 Entity로 승격
- 양 테이블의 FK를 묶어서 PK로 사용 할 수 있음
- 실제로는 독립적인 연결 엔티티만의 id를 사용하는 것이 권장.
- ID가 두 테이블에 종속되지 않을 수 있음.
Reference)
https://ict-nroo.tistory.com/127
https://velog.io/@conatuseus/%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84-%EB%A7%A4%ED%95%91-%EA%B8%B0%EC%B4%88-1-i3k0xuve9i
https://jeong-pro.tistory.com/231
https://ict-nroo.tistory.com/122