Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setUsername("member1");
member.setTeamId(team.getId());
em.persist(member);
tx.commit();
연관관계 매핑을 배우지 않으면 이렇게 객체지향스럽지 않은 코드를 짜야 한다
테이블은 외래 키로 조인을 사용해 연관된 테이블을 찾는다.
객체는 참조를 사용해서 연관된 객체를 찾는다.
@Entity
public class Member {
@Id @GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String username;
@ManyToOne
@JoinColumn(name="TEAM_ID")
private Team team;
}
@ManyToOne
: Member가 many, Team이 one
@JoinColumn
: 조인할 때 쓰는 컬럼명
이렇게 연관관계 매핑을 하면 Team을 바로 set하고 수정할 수 있다
테이블의 연관관계는 FK 하나로 양방향 연관관계가 다 있다. (JOIN 하면 되기 때문)
반면에 객체에서는 Team에서 List members
를 필드로 가져야 Member를 참조할 수 있다.
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
일대다 연관관계이고 Member 클래스의 team 필드랑 mapped 되어있다.
이렇게 Member에서 Team을 참조할 수 있고 Team에서 Member를 참조할 수 있다
객체는 가급적이면 단방향이 좋다
객체의 양방향 관계는 사실 양방향 관계가 아니라 단방향 관계 2개이다
이런 상황에서 팀을 바꾸고 싶으면 Member의 team을 바꿔야 할지 Team의 mebers를 바꿔야 할지 애매하다
FK가 있는 곳을 주인으로 정해라
FK가 있는 Member.team이 연관관계의 주인이다.
1대다
일경우 다
인 쪽이 연관관계의 주인이 되어야 한다
member.setTeam(team)
@Entity
public class OrderItem {
@Id @GeneratedValue
@Column(name="ORDER_ITEM_ID")
private Long id;
@ManyToOne
@JoinColumn(name="ORDER_ID")
private Order order;
@ManyToOne
@JoinColumn(name="ITEM_ID")
private Item item;
@ManyToOne
과 @JoinColumn
을 사용해서 연관관계를 매핑한다.
@Entity
@Table(name = "ORDERS")
public class Order {
@Id
@GeneratedValue
@Column(name="ORDER_ID")
private Long id;
@ManyToOne
@JoinColumn(name="MEMBER_ID")
private Member member;
마찬가지로 @ManyToOne
, @JoinColumn
을 사용한다.
외래 키가 있는 테이블 쪽에서만 단방향으로 연관관계 매핑을 한다.
실무에서는 jpql을 쓰거나 조회를 편리하게 하기 위해 양방향 연관관계를 추가하는 경우가 있다.
@Entity
@Table(name = "ORDERS")
public class Order {
@Id
@GeneratedValue
@Column(name="ORDER_ID")
private Long id;
@ManyToOne
@JoinColumn(name="MEMBER_ID")
private Member member;
@OneToMany(mappedBy = "order")
private List<OrderItem> orderItems;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status;
양방향 연관관계를 추가한다면 다음과 같이 mappedBy
를 사용한다.