본문 바로가기
JPA

[JPA] @ManyToOne , @OneToMany, @JoinColumn

by onejunu 2020. 8. 6.

데이터 베이스공부를 하다보면 조인이라는 개념을 배운다. 

 

우리가 아는 가장 기본적인 조인은 두개의 테이블의 공통적인 요소를 끌고 오는 것이다. 

 

예를 들어 과일상자테이블과 과일들의 테이블이 있다고 하자.

 

과일상자 기본키 과일상자 이름
1 상자1
2 상자2
과일의 기본키 과일상자의 기본키(왜래키) 과일 이름
3 1 사과
4 1 포도
5 1
6 2 오렌지
7 2 바나나

 

과일상자와 과일의 관계는 OneToMany이다.

 

두개의 테이블을 조인하면 어떻게 될까?

 

과일상자를 왼쪽으로 두고 left join을 했다고 가정하자.

 

과일상자 기본키 과일상자 이름 과일의 기본키 과일 이름
1 상자1 3 사과
1 상자1 4 포도
1 상자1 5
2 상자2 6 오렌지
2 상자2 7 바나나

 

이렇게 해서 "상자1" 과 "상자2" 에 뭐가 담겼는지 알수 있다.

 

 

위 처럼 데이터베이스는 원하는 정보를 테이블의 조인을 통해 가져오는 경우가 많다. 일반적으로 조인을 하는 경우는 연관관계가 있는 경우가 많다. 물론 연관관계가 없는 테이블끼리 조인도 많이 한다.

 

위 테이블을 보면 알지만 과일의 테이블에 과일상자의 외래키를 들고 있다. 이러한 외래키를 객체세상에서는 어떻게 표현해야할까? 또한 누가 외래키를 관리해야하는가??

 

이를 위해 JPA에서 어노테이션을 제공한다. 

 

@ManyToOne

다대일로 매핑된다. 여기서는 One에 해당하는 객체와 매핑해주면 된다. 

예) 

class 과일{

    @ManyToOne

    과일상자 상자;

}

 

@JoinColumn

 

보통 Many에 해당하는 객체가 외래키를 관리한다. 이는 조금만 생각해보면 당연하다. 따라서 ManyToOne과 가장 자주 나타나는 녀석이 바로 JoinColumn 이다.

 

해당하는 객체를 참조하는 외래키를 만들어 준다. join이 "데이터베이스테이블을 조인하다" 할 때의 조인이 아니라 그냥 참여하다의 조인이다. 필자는 이것때문에 좀 헷갈렸다.

 

 예)

class 과일{

    @ManyToOne

    @JoinColumn(name = "과일상자의 기본키")

    과일상자 상자;

}

 

name은 외래키 이름을 어떻게 정할지 지정해주는 것이다. 매핑하는 것이 아니다. 또한 아무것도 지정하지 않으면 해당 객체의 기본키 값으로 참조할 필드를 만든다. 이를 설정할 수도 있다.

 

referencedColumnName 이라는 필드가 있는데 어지간하면 디폴트 값을 쓰자.

 

 

 

@OneToMany

 

이러한 필드는 보통 객체가 컬렉션 값타입을 가지는 것을 일대다로 푸는 경우에 고려되는 대상이다. 아니면 다대일 객체에서 일대다로 양방향 연관관계를 주고 싶을때 사용한다.

 

결론부터 이야기하면 후자에 해당하는 경우 가짜매핑에 해당한다. 읽기 전용으로만 쓰는 것이다. 이경우 반드시

 

mappedBy 를 이용해서 외래키를 관리하지 않는다고 명시해야한다.

 

mappedBy 속성을 사용하면 해당하는 객체에 등록 및 수정이 되어도 아무런 변화가 없다.

 

예)

class 과일상자{

    @OneToMany(mappedBy="상자")

    List<과일> 과일리스트;

}

 

여기서 과일리스트는 과일리스트들을 읽기만 할수있다. 

댓글