[JPA]다양한 연관관계 매핑
다양한 연관관계 매핑
다대일, 일대일, 다대일을 알아보겠습니다.
연관관계 매핑 시 고려사항 3가지
1. 다중성
2. 단방향, 양방향
3. 연관관계의 주인
이 3가지를 고려해야 합니다
다중성
- 다대일: @ManyToOne
- 일대다: @OneToMany
- 일대일: @OneToOne
이 3가지 어노테이션을 사용하여 다중성을 고려하면 됩니다.
사실 DB랑 매핑하기 위해서 있다고 생각하면 됩니다.
단방향, 양방향
- 테이블
- 외래 키 하나로 양쪽 조인 가능
- 사실 방향이라는 개념이 없음
- 객체
- 참조용 필드가 있는 쪽으로만 참조 가능
- 한쪽만 참조하면 단방향
- 양쪽이 서로 참조하면 양방향
양방향이라는 것은 서로 주시하는?? 개념
팀 멤버로 하면 서로 방향을 보고 있다는 개념이고 서로 단방향을 하고 있다는 개념으로 받아들일 수 있습니다.
연관관계의 주인(양방향에서 나오는 개념)
- 테이블은 외래 키 하나로 두 테이블이 연관관계를 맺음
- 객체 양방향 관계는 A->B, B->A처럼 참조가 2군데(팀 멤버 느낌)
- 객체 양방향 관계는 참조가 2군데 있음. 둘 중 테이블 외래 키를 관리할 곳을 지정해야 합니다.
- 연관관계의 주인 : 외래 키를 관리하는 참조(테이블에서)
- 주인의 반대편 : 외래 키에 영향을 주지 않음, 단순 조회만 가능한 곳
위 내용은 이전 포스팅인 연관관계의 기초 부분에 더 자세히 나와있습니다.
다대일[N:1]
주로 사용되는 단방향인 멤버와 팀으로 하겠습니다.
대부분 N에 외래 키를 설정합니다.여기서는 멤버
이유는 멤버에 외래키를 설정해야 멤버를 두 명 넣어도 Team_id에 설정을 해주어 같은 팀에 넣어줄 수 있습니다.
Team에 해버리면 관계가 꼬여버립니다.
연관관계 매핑으로서는 외래 키가 있는 곳에 참조를 걸고 연관관계를 하면 됩니다.!
다대일 양방향
양방향은 위와는 다르게 Team에 List를 넣어주면 됩니다.
여기서 중요한 점은 테이블에는 영향을 받지 않는다는 점입니다. Member가 연관관계의 주인이기 때문에 Team에서 mebmers를 변화를 줘도 테이블에는 영향을 받지 않습니다.(조회만 가능)
정리를 하자면
- 외래 키가 있는 쪽이 연관관계의 주인
- 양쪽을 서로 참조하도록 개발!
여기까지는 이전 포스팅에 있는 정보입니다.
일대다[1:N]
여기서는 1이 연관관계의 주인입니다.
그러나 이러한 모델은 주로 사용되지 않습니다.
일대다 단방향
팀을 중심으로 무엇을 해보겠다는 것
멤버 입장에서 팀은 알고 싶지 않은데 팀은 멤버를 알고 싶다는 느낌을 가지고 갑니다.
이 관계의 단점은
팀에서 list mebmers를 얻어 멤버스에 추가를 하면 update문이 한 번 더 나갈 수밖에 없게 되는 상황이옵니다.
정리
- 일대다 단방향은 일대다(1:N) 에서일(1) 이연관 관계의 주인
- 테이블일 대 다관계는 항상 다(N) 쪽에 외래 키가 있음(객체와는 다른 구조 ORM이 억지로 맞혀주려고 노력하는 것)
- 객체와 테이블의 차이 때문에 반대편 테이블의 외래 키를 관리하 는특이한구조
- @JoinColumn을 꼭 사용해야 함. 그렇지 않으면 조인 테이블 방식을 사용함(중간에 테이블을 하나 추가함)
- 일대다 단방향 매핑의 단점
- 엔티티가 관리하는 외래 키가 다른 테이블에 있음
- 연관관계 관리를 위해 추가로 UPDATE SQL 실행
- 일대다 단방향 매핑보다는 다대일 양방향 매핑을 사용하자
정리!
다대일 양방향을 사용합시다~ 웬만하면~
일대일
- 일대일 관계는 그 반대 도일 대일
- 주 테이블이나 대상 테이블 중에 외래 키 선택 가능
- 주 테이블에 외래 키
- 대상 테이블에 외래 키
- 외래 키에 데이터베이스 유니크(UNI) 제약조건 추가
일대일 : 주 테이블에 외래 키 단방향
멤버를 주 엔티티로 생각하는 것 locker는 사물함
FK는 어디를 둬도 크게 상관은 없습니다.
Member에 FK를 했을 때 연관관계 매핑도 그대로 멤버에서 Locker를 연관관계 매핑을 하면 됩니다.
Member클래스에
@OneToONe
@JointColumn(name="LOCKER_ID")
private Locker locker;
위의 코드를 넣어줍니다.
일대일 단방향 정리
다대일(@ManyToOne) 단방향 매핑과 유사
일대일 양방향
양방향은 위와 똑같이 한 후 Locker에 mappedBy를 적용시켜주면 됩니다.
양방향 정리
- 다대일 양방향 매핑처럼 외래 키가 있는 곳이 연관관계의 주인
- 반대편은 mappedBy 적용