[데브코스] JPA - 연관관계 매핑

Updated: Categories:

W8D3 Part1 - 연관관계 매핑의 방향성 / 다중성 / 연관관계 주인 / 객체그래프 탐색에 대해 알아보자

연관관계 매핑

  • DB에서 테이블은 외래키를 통해 연관 관계를 맺는다.
  • Java에서 객체(Entity)끼리는 참조, 즉 주소를 통해 연관관계를 맺는다.

방향성

  • 단방향 관계 : 둘 중 한쪽만 참조하는 것
ex) 단방향 매핑
class Member {
	private long id;
	private List<Order> orders; // 회원 -> 주문
}

class Order {
	private String id;
}

Member member = new Member();
Order order = meber.getOrders().get(0); // 회원 -> 주문에 참조가 가능하다.

order.getMember() // (X)


  • 양방향 관계 : 양쪽 모두 서로 참조하는 것
  • 테이블에서의 관계는 항상 양방향임
ex) 양방향 매핑
class Member {
	private long id;
	private List<Order> orders; // 회원 -> 주문
}

class Order {
	private String id;
	private Member member; // 주문 -> 회원
}

Member member = new Member();
Order order = member.getOrders().get(0); // 회원 -> 주문 참조 (O)
order.getMember(); // 주문 -> 회원 참조 (O)
-- 양방향 조인 
SELECT * FROM member AS m JOIN orders AS o 
ON m.id = o.member_id;

SELECT * FROM orders AS o JOIN member AS m
ON o.member_id = m.id


다중성

  • 일대일 관계 (1:1) : 양쪽 엔티티가 서로 단 하나의 관계를 가지는 것
ex) 회원정보-주민등록번호 관계

Untitled Diagram drawio (1)

  • 일대다 관계 (1:N) : 한쪽 엔티티가 다른 엔티티의 여러 객체를 가질 수 있는 것
ex) 회원-주문 관계

Untitled Diagram drawio

  • 다대다 관계 (N:M) : 양쪽 엔티티 모두 1:N 관계를 가지는 것 (매핑 테이블이 필요하다.)
ex) 학생-수업 관계

Untitled Diagram drawio (2)

참고 : https://siyoon210.tistory.com/26


연관관계 주인 (mappedBy)

  • 객체를 양방향 연관관계로 만들면 관계의 주인을 정해줘야 함.
  • 외래키를 관리할 객체를 지정한다.
  • 연관관계의 주인만이 외래키를 생성/수정/삭제 할 수 있음
    • 주인이 아닌 쪽은 조회만 가능
  • 테이블 중 FK가 있는 쪽이 연관관계의 주인이 된다.
ex) 회원-주문 관계

Untitled Diagram drawio

class Member {
	...
	// 연관관계의 주인은 Order 엔티티이다. -> FK의 주인은 Order이므로 (Order에서만 member 객체를 가짐)
	// 따라서 Member 엔티티에는 Order 엔티티가 가지는 member라는 객체를 매핑시켜줘야한다
	@OneToMany(mappedBy = "member")
	private List<Order> orders;
}

class Order {
	...
	// Order 엔티티 기준 다대일 관계
	@ManyToOne
	// order 테이블의 member_id라는 컬럼을 생성 -> member 테이블의 id 컬럼을 받아서 FK 지정
	// 생략해도 자동으로 찾아서 설정된다 -> 하지만 가시성을 위해 명시
	@JoinColumn(name = "member_id", referencedColumnName = "id")	
	private Member member;
}
  • 데이터베이스 테이블의 다대일, 일대다 관계에서는 항상 ‘다’ 쪽이 외래 키를 가진다.
  • 위의 예제에서는 Member가 ‘일’, Order가 ‘다’이므로 Order가 연관관계의 주인이 된다.


객체 그래프 탐색

  • 양방향 관계일 경우 객체의 참조를 통해 서로를 가져오는 것
ex) 객체 그래프 탐색
class Member {
	private long id;
	private List<Order> orders;
}

class Order {
	private String id;
	private Member member;
}

void graph() {
    Member member1 = new Mebmer(1);
    Order order1 = new Order(1)

    // 멤버에 해당 order 엔티티를 추가해준다.
    member1.setOrders(Lists.newArrayList(order1));

    // 멤버에서 order 엔티티 가져오기
    Order findOrder= member1.getOrders().get(0); // 객체 그래프 탐색이라 한다.

    // 가져온 order 엔티티에서 멤버 가져오기
    findOrder.getMember();
}