- 다중성
- 다대일 [N:1]
- 일대다 [1:N]
- 일대일 [1:1]
- 다대다 [N:M]
- 단방향, 양방향
- 연관관계 주인
[ 설명 ]
다대일
의 뜻 :N:1
관계에서 연관관계 주인이N
인 경우- 가장 많이 사용되는 연관관계
- DB에서는 반드시
1:N
관계에서N
에 해당하는 테이블에외래키(FK)
가 들어간다
-->1
에 FK가 들어가면 말이 안됨
(Team
에MemberId
가 있다면 배열이 DB에 들어가지 않는 한 하나의TEAM_ID
에 여러개의Member
가 들어갈 수 없음)
[ 단방향 ]
- 과정 [
N
객체]
FK
로1
의 객체를 삽입@ManyToOne
+@JoinColumn(name = "{1의 PK이름}")
ex)
[ 양방향 ]
- 과정 [
N
객체]
단방향 설정
+연관관계 메서드
- 과정 [
1
객체]
List<객체>
변수 선언@OneToMany(mappedBy = {N의 필드이름})
ex)
[ 설명 ]
일대다
의 뜻 :1:N
관계에서 연관관계 주인이1
인 경우1:N
관계에서 항상N
에FK
를 넣어주기 때문에 잘 쓰이지 않는 관계- 기능적으로도 관리하는 외래 키가 다른테이블에 있어서 추가적인
UPDATE
쿼리가 나간다 --> 비효율적- 만약 꼭 필요하다면
다대일 양방향 매핑
권장
- 사용시
@JoinColumn
을 꼭 사용해야함
(default가JoinTable
이라서 테이블이 생성되기 때문)
[ 단방향 ]
- 과정 [
1
객체]
FK
로List<>
의 객체를 삽입@OneToMany
+@JoinColumn(name = "{1의 PK이름}")
ex)
[ 양방향 ]
- 과정 [
1
객체]
단방향 설정
+연관관계 메서드
- 과정 [
N
객체]
1
의 객체를 변수로 선언@ManyToOne
@JoinColumn(name = "1의 PK", insertable = false, updateable = false)
: 조회만 하도록 강제로 만들어 주는 것!
ex)
- 즉 ,
다대일
연관관계에서양방향 연관관계
와 설정은 같으나mappedBy
가 빠지고,insertable, updateable
을false
처리해서 강제로 조회만 하게만들어 준것 !
--> 굳이 사용할 일이 없음
-->다대일 양방향
을 사용하자
[ 설명 ]
- 양쪽 테이블 모두
FK
를 가질 수 있음
주 테이블
에FK
삽입대상 테이블
에FK
삽입
(주 테이블
? --> 더 자주 사용되는 테이블)
- 어떤 테이블에
FK
를 삽입하고연관관계 주인
이 될지는 고려해볼 문제
--> 그러나 보통주 테이블
에FK
를 넣고연관관계 주인
설정을 한다
FK
에DB 유니크
제약조건 추가해야함
-->
1:1
이기 때문
(사실 데이터가 그렇게 안오면 괜찮지만, 혹시모르니 해놔야함)
[ 단방향 ] - 주 테이블
다대일
관계 설정과 매우 유사 (어노테이션만 다름)주 테이블
객체
대상 테이블
객체를 참조하는 변수 선언@OneToOne
+@JoinColumn(name = "대상테이블 PK")
ex)
[ 양방향 ] - 주 테이블
주 테이블
객체
단방향 설정
+연관관계 메서드
대상 테이블
객체
주 테이블
객체 참조하는 변수 선언@OneToOne(mappedBy = "연관관계 주인의 필드명")
ex)
[ 단뱡향 ] - 대상 테이블 (불가능)
대상테이블
에FK
를 저장하는 단방향 관계는 불가능- JPA에서 지원하지 않음 / 강제로 할수도 없음
[ 양방향 ] - 대상 테이블 (가능)
FK
를대상 테이블
에서 관리하고주 테이블
의 변수는 읽기전용으로 사용된다.- 매핑하는 방법은
일대일 주 테이블 양방향
과 같다
[ 1:1 정리 ]
1:1
연관관계시주 테이블
에FK
를 넣는 것이 단순하고 많이 사용- DBA와 협의 후 필요에 따라
대상 테이블
에FK
를 넣는 양방향은 고려해볼 만 하다
주 테이블에 외래 키
- 장점
: 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인 가능- 단점
: 값이 없으면 외래 키에 null값 허용 해야함
대상 테이블에 외래 키
- 장점
: 주 테이블과 대상 테이블을일대다
로 변경시 테이블 구조 유지됨
(나중에Member
가 여러개의Locker
를 쓰게되면 어차피Locker
가연관관계 주인
이 되어야 하기 때문에 유지)- 단점
: 프록시 기능의 한계로지연 로딩
설정해도 항상 즉시 로딩됨
(값이 없으면Null
을 넣어줘야 해서 어차피 확인해야 하기 때문에즉시 로딩
됨)
[ 설명 ]
RDB
에서N:M
관계는 테이블 2개로 표현이 불가능하다
--> 테이블을 추가해서1:N
M:1
로 풀어내야함- 객체에서는
N:M
이 가능해서 JPA가@ManyToMany
을 통해 지원함- 서로의
PK
를 지정해서 알아서 테이블로 만들어주는 기능인데 권장 X
(딱 지정한Column
만 넣을 수 있기 때문
--> 차라리@Entity
를 직접만들어서 원하는Column
추가하는것 권장O)
- 즉, 실무에서
@MayToMany
사용 X
[ 사용 ]
- 기본적으로
양방향
으로 설계함
- 한쪽
List<참조객체>
선언@ManyToMany
@JoinTable(name="", joinColumns =@JoinColumn(name="한쪽 PK명"), inverseJoinColumns = @JoinColumn(name = "다른쪽 PK명")
ex)
- 다른쪽
List<참조객체>
선언@ManyToMany(mappedBy = "연관관계 주인 필드명")
ex)
[ 한계 ]
@ManyToMany
를 사용한다대다
연결은 내가 지정한Column
만 가능하다- 사용하기에 편해보이지만 유연성이 없어서
실무에서 사용하지 X
[ 대안 ]
- 실무에서는 실제로 두 테이블을 사이에 새로운
@Entity
선언해서 사용N:M
-->1:N
M:1
로 풀어서 사용한다!!- 내가원하는
Column
추가할 수 있는 유연성이 생김!
N:1
(다대일) 관계 &1:N
(주 테이블 FK)로 대부분 관계 정의 가능N:M
은 반드시1:N
&M:1
로 분리해서@Entity
추가 생성해 사용- 각
연관관계를 구현
하기 위해 적절한어노테이션
과옵션
지정을 기억하자