[Spring] 연관 관계 맵핑하기

gwonsang247·2023년 8월 18일
0

Java

목록 보기
9/11
post-thumbnail

연관 관계의 종류

관계수(cardinality)란 두 엔티티 간의 대응하는 행의 수를 말한다.
관계수의 종류는 일대일(1:1), 일대다(N:1), 다대다(M:N)이 있다.
각 관계수는 애너테이션을 사용해서 표현한다.

다대다(M:N)의 경우는 일대다(1:N) 관계수 다수로 치환되어 표현한다.


일대일(1대1) 관계 연결하기

: 단방향 연결

두 엔티티의 단방향 연결을 위해서는 @OneToOne 어너테이션을 사용해 단방향 관계 맵핑을 표시하고 @JoinColumn을 사용해서 연결하고자 하는 엔티티 내 컬럼을 지정해준다. 즉, 외래참조키를 설정하는 작업이다. 그렇기에 연결 대상이 되는 엔티티의 참조가 되는 컬럼에는 @Column을 붙여서 표시를 해줘야한다.

아래 그림에서는 Cart에서 Member 엔티티에 단방향 관계 맵핑을 하였고, Cart에서는 Member의 ID를 참조키로 하여 관계가 연관되어있다.

맵핑 결과로 Cart 객체를 통해서 Member의 정보를 가져올 수 있다.


일대일(1대1) 관계 연결하기

: 양방향 연결

양방향으로 관계를 설정하는 경우에는 두 엔티티 모두에 @JounColumn 어노테이션을 해줄 필요없이 한쪽에만 설정한다. 그 이유는 @JoinColumn을 표시하는 것은 엔티티 내에 외래 참조 키(FK)를 생성하는 것과 같은 의미이기 때문에 양쪽에 중복되는 FK를 생성하는 것은 비효율적이다. 그렇기에 한쪽에만 @JoinColumn을 지정하여 연결한다.

nullable=false는 아래처럼 사용자(Member)가 없는 장바구니(Cart)는 경우 Cart에서 참조하는 Member는 Null값이 불가능하다. 그러므로 nullable=false로 지정해야 InnerJoin이 가능하고 맵핑 성능이 좋아진다.

OneToOne(mappedBy = "member") 는 양방향 연결을 할 때 FK가 두번 생성되는 것을 막기 위한 조치로 반드시 필요하다.


다대일(N:1) 관계

: 단방향 연결

예를 들어 게시판(Board)와 사용자(User) 엔티티가 있다고 가정하면 다수의 게시글을 쓸 수 있고 하나의 게시글은 저자가 한명이므로 다대일 관계를 가진다.

@MantToOne 어노테이션을 사용해서 Board 엔티티와 User 엔티티의 관계가 다대일임 단방향으로 맵핑한다.


다대일(N:1) 관계

: 양방향 연결

@ManyToOne을 통해 다대일 연결을 하고 대상 엔티티에서 양방향 연결을 하는 경우 @OneToMany 어노테이션을 사용해 맵핑한다.

여기서 아래와 같이 mappedBy 조건을 설정하여 FK 중복 생성을 막아준다.
FetchType은 EAGER / LAZY 두 옵션을 가진다. LAZY가 디폴트 값이고 EAGER의 경우 연관된 두 엔티티의 정보를 모두 가져오고 LAZY의 경우 따로 가져온다.

아래 예시에서는 다대일을 양방향으로 맵핑하게 되고 이는 게시글을 조회하면 User(작성자: 단일값)의 정보가 확인 가능하고, 사용자를 조회하면 사용자가 작성한 Board(게시글 : 다수값) 리스트가 반환된다.

0개의 댓글