연관관계 주인 정리
다대일
연관관계 주인은 외래키를 가지고 있는 객체가 된다.
외래키를 가지는 객체는 多인 엔티티이다. 따라서 여기서는 Member가 多이므로 Member.team이 연관관계 주인이된다.
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME", nullable = false)
private String userName;
@ManyToOne
@JoinColumn(name = "TEAM_ID") //연관관계 주인
private Team team;
// 연관관계 편의 매소드
public void changeTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
}
양방향은 사실 단방향이 두개인 것이다. 연관관계 주인의 경우 단방향에서 구현한대로 똑같이 하면되고, 양방향을 구현하기 위해선 연관관계 주인이 아닌 객체도 주인 객체의 필드에 매핑을 해주어야 서로서로 조회할 수 있으므로 리스트로 필드를 만들고 @OneToMany(mappedBy = "주인 객체")로 매핑하여 읽기 전용으로 만들어준다.
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedeBy = "team") // members로는 조회만 가능. Member.team이 연관관계 주인
private List<Member> members = new ArrayList<>();
}
일대일
- 단방향
다대일과 유사하다. 주 테이블 하나 정해서 외래키 주고 연관관계 주인으로 만든다.
@Entity
public class Member { // 주테이블 MEMBER
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME", nullable = false) // 매핑할 컬럼명이 "USERNAME". + not null 설정
private String userName;
@OneToOne
@JoinColumn(name = "LOCKER_ID") //연관관계 주인
private Locker locker;
}
+α) 주 테이블 정하는 방법
예시
주 테이블은 주로 많이 접근하는 테이블을 사용한다.
위의 경우에는 Order와 Delivery가 일대일 관계인데 보통 Order를 많이 찾으니 fk를 Order에게 두고, 주인을 Order.delivery로 정하면 된다.
Order.class
package jpabook.jpashop.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter @Setter
public class Order {
@Id
@GeneratedValue
@Column(name = "order_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "delivery_id")
// 꿀팁! OneToOne일때 주인 지정: 많이 사용하는 놈한테 주인설정을 준다.
private Delivery delivery;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status;
}
Delivery.class
package jpabook.jpashop.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter @Setter
public class Delivery {
@Id
@GeneratedValue @Column(name = "delivery_id")
private Long id;
@OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY)
// Order.delivery가 주인, Delivery.order는 mappedBy 된다.
private Order order;
@Embedded
private Address address;
@Enumerated(EnumType.STRING)
private DeliveryStatus status;
}
- 양방향
@Entity
public class Locker { // 대상 테이블 LOCKER
@Id @GeneratedValue
@Column(name = "LOCKER_ID")
private Long id;
private String name;
@OneToOne(mappedBy = "locker") // 읽기 전용
private Member member;
}
주 테이블의 반대편(대상테이블)은 mappedBy 적용.
- 대상 테이블은 다대일중 일인 테이블처럼 mappedBy해주면 된다.
'Spring > JPA' 카테고리의 다른 글
JPA- @MappedSuperClass (0) | 2023.03.12 |
---|---|
JPA- 상속관계 매핑 (0) | 2023.03.12 |
JPA- 연관관계 매핑 주의점 (0) | 2023.03.05 |
JPA- 연관관계 매핑 (0) | 2023.03.05 |
JPA- 중요! 엔티티 매핑 (0) | 2023.02.28 |