연관관계 매핑 시 고려사항 3가지
1.다중성
2.단방향, 양방향
3.연관관계의 주인
다중성
다대일 일대다 일대일 다대다
애매할때는 반대로 생각해보자.(대칭성이 있기 때문!)
다대다는 실무에서 쓰면 안된다.
테이블과 객체
테이블
- 외래키 하나로 양쪽 조인 가능
객체
- 참조용 필드가 있는 쪽으로만 참조 가능
- 한쪽만 참조하면 단방향
- 양쪽이 서로 참조하면 양방향
연관관계의 주인
- 테이블은 외래키 하나로 두 테이블이 연관관계를 맺음
- 객체 양방향 관계는 A-?B, B->A 처럼 참조가 2군데
- 객체 양방향 관계는 참조가 2군데있음 둘 중 테이블의 외래키를 관리할 곳을 지정해야 함
- 연관관계의 주인 : 외래키를 관리하는 참조
- 주인의 반대편 : 외래키에 영향을 주지 않음, 단순 조회만 가능
다 쪽에 항상 외래키가 들어가줘야 함.
다대일
조회를 원한다면 반대 방향을 추가해주면 됨.(@OneToMany)
일대다
실무에서 권장하진 않음
일대다 보다는 다대일을 사용하자.!
일대일
일대일 관계는 그 반대도 일대일
주 테이블이나 대상데이블 중에 외래키 선택이 가능한다
- 주 테이블에 외래 키
- 대상 테이블에 외래키
외래키에 데이터 베이스 유니크 제약조건 추가
@Entitiy
public class Member{
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
//이렇게만 해주면 끝
}
양방향을 만들고 싶으면
@Entity
public class Locker{
@Id @GeneratedValue
private Long id;
private String name;
@OneToOne(mappedBy = "locker")
private Member member;
//요거 넣어주면 읽기 전용이 됨
}
다대일 매핑과 유사하다.
- 다대일 양방향 매핑처럼 외래키가 있는 곳이 연관관계의 주인
-반대편은 mappedBy 적용
일대일은 내 엔티티에 있는 외래키는 내가 직접 관리해야한다.
다대다
관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다.
연결 테이블을 추가해서 일대다, 다대일 관계로 풀어내야한다.
다대다 매핑의 한계
-편리해보이지만 실무에서 사용하지 않는다.
-연결 테이블이 단순히 연결만 하고 끝나지 않음
-주문시간, 수량 같은 데이터가 들어올 수 있다.
다대다 한계 극복
- 연결 테이블용 엔티티 추가(연결 테이블을 엔티티로 승격)
-@ManyToMany -> @OneToMany , @ManyToOne
@Entity
public class Member{
@Id @GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@OneToMany
private List<MemberProduct> memberProducts = new ArrayList<>();
}
@Entity
public class Product {
@Id @GeneratedValue
privare Long id;
@OneToMany(mappedBy = "product")
private List<MemberProduct> memberproducts = new ArratList<>();
}
@Entity
public class MemberProduct{
@Id @GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;
@ManyToOne
@JoinColumn(name = "PRODUCT_ID")
private Product priduct;
}
+) 웬만하면 pk는 의미없는 값을 써야한다.(@GeneratedValue를 사용해서! -> 그래야 유연성이 생긴다)
실전예제
category - 상위 - 하위 연결
@Entity
public class Category{
@Id @GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "PARENT_ID")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();
}
'스프링 > ORM JPA' 카테고리의 다른 글
영속성 컨텍스트와 OSIV (0) | 2023.10.10 |
---|---|
지연로딩과 즉시로딩 (0) | 2023.09.17 |
영속성 컨텍스트 (0) | 2023.09.12 |
고급매핑 (0) | 2023.04.06 |
양방향 연관관계 매핑 (0) | 2023.04.04 |