Relational Mapping - Basic
엔티티들은 댑부분 다른 엔티티와 연관관계를 가진다.
객체는 참조(주소)를 사용해서 연관관계를 맺고, 테이블은 외래 키를 사용해서 관계를 맺는다.
이 둘은 완전히 다른 특징을 가지며 객체 관계 매핑(ORM)에서 가장 어려운 부분이다.
연관관계 설정의 세가지 키워드
- 방향
- 단방향, 양방향
- 테이블 관계에서는 항상 양방향이며 객체의 관계에서만 두가지 방향이 존재.
- 다중성
- 일대일, 다대일, 일대다, 다대다
- 연관관계의 주인
사용되는 어노테이션
@ManyToOne, @OneToOne, @OneToMany, @ManyToMany 어노테이션과 @JoinColumn어노테이션을 사용하여 객체의 연관관계와 테이블 연관관계를 매핑할 수 있습니다.
@JoinColumn의 주요 속성
- name / 매핑할 외래 키 이름
- referencedColumnName / 외래 키가 참조하는 대상 테이블의 컬럼명
- foreignKey(DDL) / 외래 키 제약조건을 직접 지정할 수 있다. 테이블 생성할 때만 사용.
- unique, nullable, insertable, updatable..etc) / @Column의 속성과 같음.
@ManyToOne의 주요 속성
- optional / false이면 연관된 엔티티가 항상 있어야 한다.
- fetch / 글로벌 페치 전략 설정. / FetchType.EAGER, FetchType.LAZY
- cascade / 영속성 전이 기능을 사용.
@OneToMany의 주요 속성
- mappedBy / 양방향 관계 설정 시 매핑되는 상대 엔티티의 필드명으로 지정해줌.
- 연관관계의 주인이 아니면 mappedBy 속성으로 연관관계의 주인을 지정한다.
연관관계의 주인
테이블에 외래 키가 있는 곳으로 정한다.
mappedBy로 연관관계의 주인이 아님을 표시한다.
연관관계의 주인만 데이터베이스 연관관계와 매핑되고, 외래 키를 관리할 수 있다.
주인이 아닌 반대편은 읽기만 가능하고 외래키를 변경하지는 못한다.
즉 주인이 아닌 객체에 값을 입력해도 DB에 저장될 때는 무시된다.
ex. team.getMmebers().add(member1); team.getMembers().add(member2);
다만 이는 객체 관점에서는 불안정하다. ORM은 양쪽의 패러다임이 모두 중요하기 때문에 위의 코드도 수행 필요.
내용 정리
- 단방향 매핑만으로 테이블과 객체의 연관관계 매핑은 이미 완료되었다.
- 단방향을 양방향으로 만들면 반대방향으로 객체 그래프 탐색 기능이 추가된다.
- 양방향 연관관계를 매핑하려면 객체에서 양쪽 방향을 모두 관리해야 한다.