자바 ORM 표준 JPA 프로그래밍 - 다양한 연관관계 매핑

lacblueeun·2021년 1월 8일
0

springboot

목록 보기
10/17
post-thumbnail

1. 연관관계가 필요한 이유

객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없다.
테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾지만, 객체는 참조를 사용해서 연관된 객체를 찾는다.

2. 단방향 연관관계

@JoinColumn : 객체의 참조와 테이블의 외래키를 매핑 (해당 외래키의 name)

3. 양방향 연관관계

객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개다.
객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.

mappedBy : 연관관계의 주인이 아니면 mappedBy 이다. 단순히 읽는 기능만 하는 것을 추천한다.

3-1 양방향 연관관계 주의

양방향 매핑시 연관관계의 주인에 값을 입력하지 않는다.
순수한 객체 관계를 고려하면 항상 양쪽다 값을 입력해야 한다.

양방향 매피싱에 toString, lombok, JSON 생성 라이브러리 무한루프를 주의해야 한다.
컨트롤러에서 엔티티를 반환하지 말자! 엔티티가 변경되면 API스펙이 변경되어 기존에 사용하던 사람들이 문제점을 겪을 수 있다. 값만 있는 DTO로 반환하는 것을 추천한다.

연관관계 편의메소드를 이용해서 두개다 설정을 해주는 것을 잊지말자
연관관계 편의 메소드는 둘 중 하나만 해준다. 둘다 하면 문제점이 생길 수 있다.

4. 연관관계의 주인

객체의 두 관계중 하나를 연관관계의 주인으로 지정한다. 연관관계의 주인만이 외래키를 관리할 수 있다. 주인이 아닌쪽은(mappedBy)는 읽기만 가능하다.

4-1 연관관계의 주인을 누구로!?

외래 키가 있는 곳을 주인으로 정해라
onetoMany 에 mappedBy 를 정한다. 가짜매핑이다 읽기만 가능하다.
연관관계의 주인은 비즈니스적으로 중요한것이 아니라, 다쪽이 주인이 된다는 것이다.

5. 다대일 @ManyToOne

단방향 : 다대일 연관관계는 항상 다(N)에 외래 키가 있다. 주인이 아닌 객체는 조회를 위한 객체 그래프를 탐색할 때 사용한다.

양방향 : 양방향 연관관계는 항상 서로 참조해야 한다. 서로 참조하게 하려면 연관관계 편의 메소드를 작성하는 것이 좋다. (둘중 하나만 작성하는 것이 좋다. 양쪽 다 작성할 수 있지만 무한루프에 빠질 수 있기 때문에 주의해야 한다.)

6. 일대다 @OneToMany

단방향 : 일대다 단방향 매핑을 사용하면 엔티티를 매핑한 테이블이 아닌 다른 테이블의 외래 키를 관리해야 한다. 이것은 성능 문제도 있지만 관리도 부담스럽다.

양방향 : 일대다 양방향 매핑은 사실 존재하지 않는다. 데이터베이스의 특성상 다대일, 일대다 관계는 항상 다 쪽에 외래 키가 있다. 따라서 @ManyToOne 에는 mappedby 속성이 없다. 하지만 다대일 단방향 매핑을 읽기 전용 (insertable = false, updatable = false)으로 속성을 추가하면 된다.

7. 일대일 @OneToOne

일대일 관계는 양쪽이 서로 하나의 관계만 가진다. 일대일 관계는 대상 테이블 둘 중 어느 곳이나 외래키를 가질 수 있다.

객체지향 개발자들은 주 테이블에 외래 키가 있는 것을 선호한다. 주 테이블만 확인해도 대상 테이블과 연관관계가 있는지 알 수 있다.
하지만 데이터베이스 개발자들은 보통 대상 테이블에 외래 키를 두는 것을 선호한다. 이 방법의 장점은 관계를 일대일에서 일대다로 변경할 때 테이블 구조를 그대로 유지할 수 있다.

8. 다대다 @ManyToMany 💣

관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다.
그런데 객체는 테이블과 다르게 객체 2개로 다대다 관계를 만들 수 있다.
여기서 중요한것은 @JoinTable을 사용해서 연결 테이블을 바로 매핑한 것이다.

@JoinTable : 연결할 테이블을 member_product 지정한다.
joinColumns : 현재 방향인 회원과 매핑할 조인 컬럼 정보를 지정한다.
inverseJoinColumns : 반대 방향인 상품과 매핑할 조인 컬럼 정보를 지정한다.

하지만 실무에서 사용하기에는 한계가 있다. 보통 수량이나 날짜와 같은 많은 컬럼이 필요하기 때문이다. 그래서 연결 테이블을 매핑하는 연결 엔티티를 만들고 이곳에 추가한 컬럼들을 매핑해야 한다.

profile
Go for Frontend Developer 🧪

0개의 댓글