티스토리 뷰
객체와 테이블 연관관계 차이를 이해하고, 객체의 참조와 테이블의 외래키를 매핑할 수 있어야 합니다.
객체를 테이블에 맞춰 데이터 중심으로 모델링하면 협력관계를 만들 수 없습니다. 테이블은 반드시 외래키로 조인을 해서 연관된 테이블을 찾고, 객체는 참조를 사용해서 연관된 객체를 찾습니다 ex) member.getTeam(). 따라서 테이블과 객체 사이에는 이런 큰 간격이 존재하게 됩니다.
단방향 연관관계
테이블의 연관관계는 외래 키 하나로 양방향이 존재합니다. 즉 테이블의 연관관계는 양방향이라는 것이 없다고 할 수 있습니다. 왜냐하면 외래키 하나만 있으면 양쪽 테이블에 관해 알 수 있기 때문입니다. MEMBER.TEAM_ID 외래 키 하나로 연관관계를 가지고 양쪽 조인이 가능합니다.
SELECT *
FROM MEMBER M
JOIN TEAM T on M.TEAM_ID = T.TEAM_ID
SELECT *
FROM TEAM T
JOIN MEMBER M on T.TEAM_ID = M.TEAM_ID
문제는 객체입니다. 객체를 테이블에 맞춰 데이터 중심으로 모델링하면 협력 관계를 만들 수 없습니다. Member -> Team으로 단방향 관계가 존재한다고 하면 Team이 Member에 관하여 알고 싶을 때는 알 방법이 없기 때문에 Team에도 Member를 가질 수 있는 리스트가 있어야합니다.
양방향 연관관계, 연관관계 주인과 mappedBy
객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개입니다. 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 합니다.
class A(){
B b;
}
class B(){
A a;
}
// A -> B: a.getB()
// B -> A: b.getA()
만약 내가 새로운 팀에 들어가고 싶으면 Member에 있는 team 객체를 수정해야 할까 아니면 Team에 있는 Member List를 수정해야 할까? 라는 궁금증이 생깁니다. 데이터베이스 입장에서는 외래 키 값만 업데이트 되면 됩니다. 즉, 둘 중 하나로 외래키를 관리해야 합니다.
이 때 외래키를 관리하는 객체의 멤버를 연관관계 주인(Owner)이라고 합니다.
연관관계의 주인의 몇 가지 속성이 있습니다
1. 객체의 두 관계중 하나를 연관관계의 주인으로 지정합니다.
2. 연관관계의 주인만이 외래키를 관리(등록, 수정)할 수 있습니다.
3. 주인이 아닌 쪽은 읽기만 가능합니다.
4. 주인은 mappedBy 속성을 사용하지 않습니다.
5. 주인이 아니면 mappedBy 속성으로 주인을 지정합니다.
그러면 누구를 주인으로 지정해야 할까?
-> 외래 키가 있는 곳을 주인으로 지정해주면 됩니다.
위 예제에서는 Member.team이 연관관계의 주인이고, 1:N 관계에서는 N이 연관관계의 주인입니다.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
// 연관관계의 주인 !!
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
//-------------------------------------------------------------//
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
// 주인이 아니기 때문에 mappedBy로 매핑
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
}
양방향 매핑 시 가장 많이 하는 실수
- 연관관계의 주인에 값(mappedBy)을 입력하지 않음 -> 역방향으로 설정하기 때문에 값 쓰이지 X
- 양방향 매핑 시에는 양쪽에 값을 다 세팅하는게 좋다
- 양방향 매핑 시 무한 루프를 조심 -> toString(), lombok, JSON 생성 라이브러리
- 컨트롤러에서는 entity를 반환 X. 엔티티는 dto로 변환해서 반환.
'Spring' 카테고리의 다른 글
[Spring] JPA 다양한 연관관계 매핑 (0) | 2022.05.29 |
---|---|
[Spring] Web Layer (스프링 웹 계층) (0) | 2022.05.25 |
[Spring] JPA 엔티티 매핑 (0) | 2022.05.09 |
[Spring] JPA Entity Manager 영속성 컨텍스트 (0) | 2022.04.26 |
[Spring] JUnit4 -> JUnit5 에서의 테스트 @Test, @RunWith, @SpringBootTest (0) | 2022.04.12 |
- Total
- Today
- Yesterday
- 파이썬
- 피움
- 2차 데모데이
- dm-zoned
- ZNS SSD
- dm-zoned 코드분석
- 피움 6주차 회고
- jpa
- 환경 별 로깅 전략 분리
- java
- 알림기능개선기
- 알림개선기
- 네트워크
- 우테코
- 백준
- 8주차 회고
- 회고
- 런칭 페스티벌
- 5주차 회고
- 스프링 부트
- ZNS
- CI/CD
- 3차 데모데이
- Spring
- 우테코 회고
- 스프링MVC
- 팀프로젝트
- 스프링 프레임워크
- 스프링 Logback
- 프로젝트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |