[데브코스] JPA - 연관관계 매핑
Updated: Categories: TILW8D3 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) 회원정보-주민등록번호 관계
일대다
관계 (1:N) : 한쪽 엔티티가 다른 엔티티의 여러 객체를 가질 수 있는 것
ex) 회원-주문 관계
다대다
관계 (N:M) : 양쪽 엔티티 모두 1:N 관계를 가지는 것 (매핑 테이블이 필요하다.)
ex) 학생-수업 관계
참고 : https://siyoon210.tistory.com/26
연관관계 주인 (mappedBy)
- 객체를 양방향 연관관계로 만들면 관계의 주인을 정해줘야 함.
- 외래키를 관리할 객체를 지정한다.
- 연관관계의 주인만이 외래키를 생성/수정/삭제 할 수 있음
- 주인이 아닌 쪽은 조회만 가능
- 테이블 중 FK가 있는 쪽이 연관관계의 주인이 된다.
ex) 회원-주문 관계
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();
}