<목표>
- 객체와 테이블 연관관계의 차이를 이해
- 객체의 참조와 테이블의 외래 키를 매핑
<용어이해>
- 방향(Direction) : 단방향, 양방향
- 다중성(Multiplicity): 다대일(N:1) , 일대다(1:N), 일대일(1:1), 다대다(N:M) 이해
- 연관관계의 주인(Owner) : 객체 양방향 연관관계는 관리 주인이 필요
1. 연관관계가 필요한 이유
- 객체지향 설계의 목표는 자율적인 객체들의 협력공동체를 만드는 것이다. by조영호(객체지향의 사실과 오해)
- 객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력관계를 만들 수 없다.
- 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾는다.
- 객체는 참조를 사용해서 연관된 객체를 찾는다.
- 테이블과 객체 사이에는 이런 큰 간격이 있다.
- 참조 대신 외래키를 그대로 사용하였다 -> 객체를 테이블에 그대로 맞추어 모델링
- Member 에 team_id를 저장하기 위해서 team객체의 아이디를 받아와서 다시 저장하는것은 객체 지향적인 방법이 아니다.
2. 단방향 연관관계
- 객체의 참조와 테이블의 외래 키를 매핑하였다 -> 객체 지향 모델링
- Team에서 getId를 받아와서 teamId를 저장하는 방법보다 훨신 객체 지향적이다.
member.setTeamId(team.getId())
3. 양방향 연관관계와 연관관계의 주인
양방향 매핑 ( Member 엔티티에서도 team 참조, Team 엔티티에서도 member 참조 )
-Member 엔티티는 단방향과 동일하게
- Team 엔티티에서 @OneToMany 추가후 mappedBy = "team" .
- List<Member> members = new ArrayList<Member>();
mappedBy
- 객체와 테이블이 관계를 맺는 차이를 이해해야 한다.
- JPA의 멘붕 난이도..
< 객체와 테이블이 관계를 맺는 차이>
- 테이블 연관관계 = 1개
- 회원<-> 팀의 연관관계 1개 (양방향)
- 객체 연관관계 = 2개
- 회원 -> 팀 연관관계 1개 (단방향)
- 팀 -> 회원 연관관계 1개 (단방향)
* 객체의 양방향 관계
- 객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개다.
- 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.
- A -> B 로 가고 싶을 때 : a.getB()
- B -> A 로 가고 싶을 때: b.getA()
* 테이블의 양방향 연관관계
- 테이블은 외래 키 하나로 두 테이블의 연관관계를 관리
- MEMBER.TEAM_ID 외래키 하나로 양방향 연관관계로 가짐 (양쪽으로 조인할 수 있다.)
따라서, 테이블과 객체의 관계 맺는 차이 때문에
객체는 객체의 두 관계 중 하나를 연관관계의 주인으로 정해야한다.
아래와 같은 그림에서는 team으로 연관관계의 주인으로 하는게 좋을까? members를 연관관계의 주인으로 하는게 좋을까?
* 연관관계의 주인 (Owner)
양방향 매핑 규칙
- 객체의 두 관계 중 하나를 연관관계의 주인으로 지정
- 연관관계의 주인만이 외래키를 관리 (등록, 수정)
- 주인이 아닌쪽은 읽기만 가능
- 주인은 mappedBy 속성 사용 X
- 주인이 아니면 mappedBy 속성으로 주인 지정
누구를 연관관계의 주인으로 정할 것인가?
- 외래 키가 있는 곳을 주인으로 정해라.
- 여기서는 Member.team이 연관관계의 주인
- ManyToOne "다" 쪽에 연관관계의 주인으로 해라.
* 주의 ! 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하자.
- 연관관계의 주인에 값 설정은 필수이며, 주인이 아닌 방향에도 값 설정을 해 주는 것이 좋다.
team.getMembers().add(member) // 연관관계의 주인이 아닌 방향에도 값 설정
member.setTeam(team) // 연관관계의 주인에 값 설정
- 실수로 까먹는 경우가 생길 수 있으므로, 연관관계 편의 메서드를 사용하자.
- ex. Member객체 안에 member와 Team을 둘다 저장하는 메서드를 만들어 사용하자. member.changeTeam(team)
* 주의 ! 양방향 매핑 시에 무한 루프를 조심하자.
- toString(), lombok, JSON 생성 라이브러리
* 단방향 매핑만으로 연관관계 매핑 완료할 수 있고, 추가로 양방향이 필요할때 나중에 추가하면 됨.
* JPQL에서 역방향으로 탐색할 일이 많음.
( 해당 글은 인프런- 자바 ORM 표준 JPA 프로그래밍 수업 및 제공되는 자료를 바탕으로 작성하였습니다. )
'Spring > 자바 ORM 표준 JPA프로그래밍' 카테고리의 다른 글
고급매핑 : 상속관계 매핑 /@MappedSuperclass (0) | 2022.05.10 |
---|---|
다양한 연관관계 매핑 (0) | 2022.05.08 |
엔티티 매핑 (0) | 2022.05.06 |
영속성 컨텍스트 (0) | 2022.05.05 |
JPA 소개 (0) | 2022.05.05 |