연관관계의 필요성
객체지향 설계의 목표는 객체들간의 협력 공동체를 만드는 것이다.
@JoinColumn
외래키를 참조할 때 사용한다. 즉, 외래키에 달아준다.
- 속성
- name
- referencedColumnName
- foreignKey
- unique/nullable/insertable/updatable/columnDefinition/table
@ManyToOne
다대일 관계 매핑
- 속성
- optional
- fetch
- cascade
- targetEntity
@OneToMany
다대일 관계 매핑
- 속성
- mappedBy
- fetch
- cascade
- targetEntity
단방향 연관관계
- FK 로 연관된 테이블의 PK 를 참조시킨다.
- FK 에 @JoinColumn(name = "...") 로 설정할 수 있다.
양방향 연관관계
- 테이블 관점에서의 양방향 연관관계
- 하나의 외래 키로 두 테이블의 연관관계를 관리하는 것
- 사실 방향이라는 개념이 없음
- e.g)
A<->B
- 객체 관점에서의 양방향 연관관계
- 서로 다른 단방향 관계 2 개
- 참조용 필드가 있는 쪽으로만 참조 가능
- e.g)
A->B
, B->A
연관관계의 주인
양방향 매핑의 두 객체중 하나를 연관관계의 주인으로 지정해야 한다. 연관관계의 주인만이 외래 키를 관리하고, 주인이 아닌쪽은 읽기만 가능하다.
- 주인이 아닌 곳에서
mappedBy
속성으로 주인을 지정해줘야 한다.
mappedBy
는 읽기 전용으로, 값을 넣어도 DB 에 적용되지 않는다.
- 연관관계의 주인은 외래 키가 있는 쪽을 기준으로 정해야 한다.
연관관계의 주인
: 외래 키를 관리하는 참조
주인의 반대편
: 외래 키에 영향을 주지 않고 단순 조회만 가능하다.
주의 : 연관관계의 주인에 값을 꼭 입력해야 한다. (순수한 객체 관계를 고려해 양쪽에 값을 넣어주자)
참고 : N대M 의 N쪽이 연관관계의 주인이다. (의도적으로 배치했음)
다대일 [N:1]
다대일 단방향
- 가장 많이 사용하는 연관관계로 多 쪽에 외래 키가 있고, 연관관계의 주인이 된다.
다대일 양방향
- 양쪽을 서로 참조하도록 개발하자.
- 외래키가 있는 쪽이 연관관계의 주인이 된다.
일대다 [1:N]
일대다 단방향
- 1:N 에서 1이 연관관계의 주인이다.
- 항상 N 쪽에 외래 키가 있다.
- 여기서 의문점이 있을 것이다. 보통 多 쪽이 연관관계의 주인이 된다고 했기 때문이다.
- 객체 기준에서는 Member(N)은 Team(1)을 모르고 있다. 그러나 Team(1)은 자신에게 속한 모든 Member(N)들을 알고 있다. Member(N)에게 외래 키가 없기 때문에 어쩔 수 없이 Team(1)에 외래키가 존재하는 상황이 발생한 것이다.
- 객체와 테이블의 차이 때문에 반대편 테이블의 외래키를 관리하는 특이한 구조
- @JoinColumn 을 꼭 사용해줘야 한다. 그렇지 않으면 조인 테이블 방식을 사용하게 됨
=> 일대다 단방향 매핑보다는 다대일 양방향 매핑을 사용하자
일대일[1:1]
일대일 단방향 매핑
- 주 테이블이나 대상 테이블 중 외래 키를 선택할 수 있다. 즉, 양쪽 어디든 들어갈 수 있음
- 외래 키에 DB 유니크(UNI) 제약조건 추가
- 반대편에
mappedBy
를 추가하면 양방향으로 만들 수 있다.
- 단방향 관계는 JPA 에서 지원하지 않는다
- 양방향 관계는 지원함
다대다[N:M]
- 관계형 DB 는 정규화된 테이블 2개로 다대다 관계를 표현할수 없다.
- 연결 테이블을 추가해 일대다 + 다대일 관계로 풀어내야만 한다.
- 다만 객체는 객체 2개로 다대다 관계가 가능하다!
- 편리해보이지만 실무에선 사용하지 않는다.
- 연결 테이블은 매핑만 하고 끝나지 못한다. 실무에서는 요구 데이터가 필요한 경우가 분명 생기기 때문이다.
- 예를 들어서, 주문 시간이나 수량 같은 데이터가 들어갈 수 있다.
- @ManyToMany 에는 필드가 추가할 수 없고 엔티티 테이블이 불일치하기 때문에 사용하지 말아야 한다.
다대다의 한계 극복
- 연결 테이블용 엔티티를 추가한다.
- @ManyToMany -> @OneToMany, @ManyToOne
출처