아래 내용은 김영한님의 '자바 ORM 표준 JPA 프로그래밍' 책의 내용을 요약하였습니다.
[JPA] Chapter 5. 연관관계 매핑 기초
- 엔티티들은 대부분 다른 엔티티와 연관관계가 있다.
- chapter 5의 목표 : 객체의 참조와 외래 키를 매핑하는 것
5.1 단방향 연관관계
회원과 팀의 관계를 통해 다대일 단방향 관계를 알아보자
- 회원과 팀이 있다
- 회원은 하나의 팀에만 소속될 수 있다.
- 회원과 팀은 다대일 관계다.
객체 연관관계
- 회원 객체는 Member.team 필드(멤버변수)로 팀 객체와 연관관계를 맺는다.
- 회원 객체와 팀 객체는 단방향 관계다.
- Member.team 필드를 통해 팀을 알 수 있다. 즉, member에서 Team 조회는 member.getTeam()으로 가능
테이블 연관관계
- 회원 테이블은 TEAM_ID 외래 키로 팀 테이블과 연관관계를 맺는다.
- 회원 테이블과 팀 테이블은 양방향 관계다.
- MEMBER 테이블의 TEAM_ID 외래 키 하나로 MEMBER JOIN TEAM과 TEAM JOIN MEMBER 둘 다 가능
// 외래 키 하나로 양방향 조인
// 1. 회원과 팀 조인
Select *
From MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
// 2. 팀과 회원 조인
select *
from TEAM T
JOIN MEMBER M ON T.TEAM_ID = M.TEAM_ID
객체 연관관계와 테이블 연관관계의 차이
- 참조를 통한 연관관계는 언제나 단방향
- 객체는 양방향 관계가 아니라 서로 다른 단방향 관계 2개
- 테이블은 외래키 하나로 양방향으로 조인할 수 있다.
- ------
- 객체는 참조(주소)로 연관관계를 맺음
- 테이블은 외래키로 연관관계를 맺음
=> 즉, 연관된 데이터를 조회할 때 객체는 참조( a.getB().getC() )를 사용하지만 테이블은 JOIN 사용
5.1.1 순수한 객체 연관 관계
객체 그래프 탐색
: 객체는 참조를 사용해서 연관 관계를 탐색할 수 있음
public static void main(String[] args) {
// 생성자(id,이름)
Member member1 = new Member ("memberl", "회원1");
Member member2 = new Member ("member2", "회원2");
Team team1 = new Team ("team1" , "팀1") ;
member1.setTeam(team1);
member2.setTeam(team1);
Team findTeam = member1.getTeam();
}
5.1.2 테이블 연관관계
데이터베이스는 외래 키를 사용해서 연관관계를 탐색할 수 있는데 이것을 조인이라 한다
// 회원1이 소속된 팀 조회
select T.*
From MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
WHERE M.MEMBER_ID = 'member1'
5.1.3 객체 관계 매핑
// 매핑한 회원 엔티티
@Entity
public class Member {
@Id
@Column(name ="MEMBER_ID")
private Long id;
private String username;
//연관관계 매핑
@ManyToOne
@JoinColumn(name="TEAM_ID")
private Team team;
//연관관계 설정
public void setTeam(Team team) {
this.team = team;
}
}
// 매핑한 팀 엔티티
@Entity
public class Team {
@Id
@Column(name = "TEAM_ID")
private Long id;
private String name;
}
@ManyToOne
- 다대일(N:1) 관계라는 매핑 정보(회원과 팀)
- 연관관계를 매핑할 때 이렇게 다중성을 나타내는 어노테이션 필수
@JoinColumn(name="TEAM_ID")
- 조인 컬럼은 외래 키를 매핑할 때 사용
- name 속성에는 매핑할 외래 키 이름 지정
- 이 어노테이션 생략 가능
5.1.4 @JoinColumn
외래 키 매핑할 때 사용
속성
name
- 매핑할 외래 키 이름
referencedColumnName
- 외래 키가 참조하는 대상 테이블의 컬럼명
foreignKey(DDL)
-외래 키 제약조건을 직접 지정 가능
-테이블 생성할 때만 사용
5.1.5 @ManyToOne
: 다대일 관계에서 사용
속성
optional
- false로 설정하면 연관된 엔티티가 항상 있어야 한다.(default:true)
fetch, cascade, targetEntity ...
5.4 연관관계의 주인
- 테이블은 외래 키 하나로 두 테이블의 연관관계를 관리
- 엔티티를 단방향으로 매핑하면 참조를 하나만 사용
- 엔티티를 양방향 연관관계로 설정하면 객체의 참조는 둘인데 외래 키는 하나다. 따라서 둘 사이에 차이 발생
JPA에서는 두 객체 연관관계 중 하나를 정해서 테이블의 외래 키를 관리해야 하는데 이것을 연관관계의 주인
5.4.1 양방향 매핑의 규칙: 연관관계의 주인
- 연관관계의 주인만이 데이터베이스 연관관계와 매핑되고 외래키를 관리할 수 있다.
- 반면에 주인이 아닌 쪽은 읽기만 할 수 있다.
- mappedBy를 사용하여 연관관계의 주인을 지정할 수 있다.
**주인은 mappedBy 속성 사용X, 주인이 아니면 속성을 사용해서 속성 값으로 연관관계의 주인을 지정해야 함 - 연관관계의 주인을 정한다는 것은 사실 외래 키 관리자를 선택하는 것이다.
5.4.2 연관관계의 주인은 외래 키가 있는 곳
- 연관관계의 주인은 테이블에 외래키가 있는 곳으로 정해야 한다.
- 다대일, 일대다 관계에서는 항상 다 쪽이 외래 키를 가진다.
다 쪽인 @ManyToOne은 항상 연관관계의 주인이 되므로 mappedBy 속성이 없다.
정리
- 양방향의 장점은 반대방향으로 객체 그래프 탐색 기능이 추가된 것뿐이다.
- 단방향 매핑만으로 테이블과 객체의 연관관계 매핑은 이미 완료
- 단방향을 양방향으로 만들면 반대방향으로 객체 그래프 탐색 기능이 추가된다.
- 양방향 연관관계를 매핑하려면 객체에서 양쪽 방향을 모두 관리해야 한다.
- 연관관계의 주인은 외래 키의 위치와 관련해서 정해야지 비즈니스 중요도로 접근하면 안 된다.
Reference)
자바 ORM 표준 JPA 프로그래밍 - 김영한 지음
'Server' 카테고리의 다른 글
[AWS] 탄력적 IP 할당부터 ssh 접속까지 (0) | 2023.08.08 |
---|---|
[AWS] EC2 인스턴스 제대로 생성하기 (0) | 2023.08.08 |
[JPA] Chapter 4. 엔티티 매핑 2 (1) | 2023.05.17 |
[JPA] Chapter 4 엔티티 매핑 1 (0) | 2023.05.11 |
[JPA] Chapter 3 영속성 관리 (0) | 2023.05.05 |