JPA에서 가장 중요한 2가지 POINT!
1. 객체와 관계형 데이터 베이스 매핑하기 (ORM)
2. 영속성 컨텐스트
ORM이란?
1. Objected-Relational Mapping (객체 관계 매핑)
2. 객체는 객체대로 설계
3. 관계형 데이터베이스는 관계형 데이터베이스대로 설계
4. ORM 프레임워크가 중간에서 매핑! (다리 역할)
연관관계 매핑 시 고려사항 3가지 POINT!
1. 다중성 ex) 1:N / N:1 / N:N / 1:1
2. 단방향, 양방향 여부
3. 연관관계의 주인 (외래키가 있는 곳을 주인으로 설정 + 주인 측에 값을 넣는 것이 통상적임)
연관관계 매핑이란?
객체의 참조와 테이블의 외래키를 매핑하는 것!
예시)
1. 회원과 팀이 있다.
2. 회원은 하나의 팀에만 소속될 수 있다.
3. 회원과 팀은 다대일 관계이다.
▼ N:1 단방향 테이블 모델링 (객체참조 연관관계가 없는 테이블버전)
=> 객체를 테이블에 맞춰 데이터 중심으로 모델링할 시, 협력관계를 만들 수 없다!
> 테이블은 외래키로 조인을 사용해서 연관된 테이블을 찾는다.
> 객체는 참조를 사용해서 연관된 객체를 찾는다.
위 두 패러다임 차이를 해소시켜야 한다.
▼ N:1 양방향 객체의 참조와 테이블의 외래키를 서로 맞춰 모델링 (위 : 객체버전 / 아래: 테이블버전)
★ 현재 객체버전은 양방향으로 서로 걸려있다. (Team 객체에 List members가 있기때문!)
member 객체 안 team(FK)값은 객체 방식으로 아래와 같이 표현된다.
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
team 객체 안 List members값은 객체 방식으로 아래와 같이 표현된다.
@OneToMany(mappedBy = "team")
위 어노테이션을 통해 연관관계의 주인,
즉 외래키를 관리하는 필드(Member의 team 필드)를 명시해주었다.
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
...
}
양방향 연관관계
객체 연관관계 = 2개 [참조값]
회원 -> 팀 연관관계 1개(단방향)
팀 -> 회원 연관관계 1개(단방향)
테이블 연관관계 = 1개 [외래키]
회원 <-> 팀 연관관계 1개(양방향)
▶ 객체의 양방향 관계는 사실 양방향 관계가 아니라, 서로 다른 단방향 관계 2개이다!
▶ 객체를 양방향으로 참조하려면, 단방향 연관관계를 2개 만들어야 한다.
양방향 매핑규칙
> 객체의 두 관계중 하나를 연관관계의 주인으로 지정
> 연관관계의 주인만이 외래키를 관리 (등록, 수정) + 값을 넣는 곳은 꼭 주인으로!
> 주인이 아닌 쪽은 읽기만 가능
> 주인은 mappedBy 속성 사용 X
> 주인이 아니면 mappedBy 속성으로 주인 지정
그럼, 누구를 주인으로 해야하는가?
★★★ 외래키가 있는 곳을 주인으로 하라!★★★★ (거의 N쪽이 연관관계의 주인이다)
위 상황에선 member.team이 연관관계 주인이다.
참고사항
양방향 매핑 시, 순수한 객체관계를 고려하면 사실 양쪽 다 값을 입력해야 한다.
이를 해소하기 위해 "연관관계 편의 메소드"라는 게 있으니 별도로 공부해야 한다.
양방향 매핑정리
> 단방향 매핑으로도 어지간한 연관관계 매핑은 완료된다. 그러니 웬만하면 단방향 설계로 마무리하는 걸 권장한다.
WHY? 양방향 매핑 시 관리측면이 더 들어가기 때문에.
> 양방향 매핑은 반대방향으로 조회하는(객체 그래프 탐색) 기능이 추가된 것뿐이다
> 허나 JPQL 사용 시에는 역방향으로 탐색할 일이 많다 (나중에 가서 공부해야함)
> 단방향 매핑 위주로 작업하고, 필요할 시에 양방향을 추가해도됨 (어차피 테이블에 영향을 주지않으니까!)
'Spring' 카테고리의 다른 글
Spring. Filter/Interceptor (0) | 2022.10.13 |
---|---|
Spring. 영속성이란 (persistence) (0) | 2022.10.13 |
Spring. Form input값 DTO 자동 주입 (1) | 2022.10.08 |
Spring. @AuthenticationPrincipal이란? (0) | 2022.10.07 |
Spring. Model객체 / model.addAttribute (0) | 2022.10.07 |
댓글