단방향 연관관계
- @ManyToOne
- 아래 예시 코드에서 Many는 Member(테이블명)이고, One은 Team(컬럼명)이다.
- '하나의 Team에 여러명의 Member가 있다' 로 이해할 수 있다.
@Entity
@Getter
@Setter
public class Member {
@Id
@Column(name = "member_id")
private String id;
private String username;
@ManyToOne
@JoinColumn(name="team_id")
private Team team;
public void setTeam(Team team) {
this.team = team;
}
}
@Entity
@Getter
@Setter
public class Team {
@Id
@Column (name = "TEAM_ID")
private String id;
private String name;
}
양방향 연관관계
연관관계 설명을 위해 배달주문 애플리케이션을 가정해 3개의 엔티티를 예시로 사용하겠다.
- Member : 사용자
- Orders : 주문 내역
- Food : 주문할 수 있는 음식
- Member 엔티티
@Getter
@Entity
@NoArgsConstructor
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String memberName;
@OneToMany(mappedBy = "member", fetch = FetchType.EAGER)
private List<Orders> orders = new ArrayList<>();
public Member(String memberName) {
this.memberName = memberName;
}
}
- Member 엔티티(테이블)의 orders 필드(컬럼)
- 사용자(Member)는 여러번 주문(orders)할 수 있으므로, @OneToMany 연관관계를 갖는다.
- Orders 엔티티
@Getter
@Entity
@NoArgsConstructor
public class Orders {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "food_id")
private Food food;
@ManyToOne
@JoinColumn(name = "member_id")
private Member member;
public Orders(Food food, Member member) {
this.food = food;
this.member = member;
}
}
- Orders 엔티티(테이블)의 food 필드(컬럼)와 member 필드(컬럼)
- 주문(Orders) 한건에 음식(food) 한가지와 주문한 사람(member) 한명을 포함할 수 있으므로 @ManyToOne 연관관계
를 갖는다.
- Food 엔티티
@Getter
@Entity
@NoArgsConstructor
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String foodName;
@Column(nullable = false)
private int price;
@OneToMany(mappedBy = "food",fetch = FetchType.EAGER)
private List<Orders> orders = new ArrayList<>();
public Food(String foodName, int price) {
this.foodName = foodName;
this.price = price;
}
}
- Food 엔티티(테이블)의 orders 필드(컬럼)
- 하나의 음식(Food)는 여러번 주문(orders)될 수 있으므로, @OneToMany 연관관계를 갖는다.
- 양방향 연관관계 Many 쪽에서 살펴보기
// Member의 Team쪽 (단방향 연관관계 예시 코드)
@ManyToOne
@JoinColumn(name="team_id")
private Team team;
// Orders의 Member쪽 (양방향 연관관계 예시 코드 중 Orders 엔티티)
@ManyToOne
@JoinColumn(name=" member_id")
private Member member;
- Many의 경우 단방향과 양방향 모두 코드 작성에서 차이가 없으며, 기본적으로 DB의 외래키는 양방향에서 조회가 가능하기 때문에 DB 상에서도 차이가 없다.
- 양방향 연관관계 Many 반대쪽에서 살펴보기
// Member의 Orders 쪽 (양방향 연관관계 예시)
@OneToMany(mappedBy = "member", fetch = FetchType.EAGER) // 단방향에는 없던 어노테이션!
private List<Orders> orders = new ArrayList<>();
- 사실 객체에는 양방향 연관관계라는 것이 없으며, 서로 다른 단방향 연관관계를 잘 묶어 양방향으로 보이게 한 것이다.
- Member 엔티티에 Orders 엔티티의 주소값을, Orders 엔티티에 Member 엔티티의 주소값을 가지고 있는 것이다. - 그러나 외래키(FK)는 양방향 연관관계를 갖는 두 개의 엔티티 중 하나의 엔티티만 가지면 된다.
- 외래키를 관리하는 엔티티를 연관관계의 주인이라고 하며, 연관관계의 주인만이 DB 연관관계와 매핑되고 외래키를 관리(등록, 수정, 삭제)할 수 있다.
- 주인이 아닌 엔티티는 읽기만 가능하다. - 연관관계의 주인은 mappedBy를 통해 이루어지며, 연관관계의 주인을 정함으로써 외래키와 관리자를 선택할 수 있다.
댓글