본문 바로가기
Jpa

연관관계 기초 매핑

by k0o9 2021. 1. 9.

참고 이글은 자바 ORM 표준 JPA프로그래밍을 읽고 정리한 글입니다.

엔티티들은 대부분 다른 엔티티와 연관관계가 있다. 객체는 참조를 사용해서 관계를 맺고 테이블은 외래키를 사용해서 관계를 맺는다. 이번에는 객체의 참조와 테이블의 외래키를 매핑해보도록 하겠다.

단방향 연관관계

자 회원과 팀의 관계를 통해 다대일 단방향 관계를 알아보겠다.

 

-회원과 팀이 있다.

-회원은 하나의 팀에만 소속될 수 있다.

-회원과 팀은 다대일 관계이다

 

자 객체 Member는 객체 Team을 가지고 있어야 참조를 통해 팀을 구할수 있다. 그에 반해 Member테이블은 외래키로 team_id를 가지고만 잇어도 팀을 구할 수 있다. 

 

객체 연관관계 

-회원 객체는 Member.team필드로 팀 객체와 연관관계를 맺는다.

-회원 객체와 팀 객체는 단방향 관계이다. 회원은 참조를 통해 팀을 알수 있지만 팀은 회원을 알 수 없다.

 

테이블 연관관계

-회원 테이블은 team_id 외래키로 팀 테이블과 연관관계를 맺는다.

-회원 테이블과 팀 테이블은 양방향 관계다. team_id를 조인해서 회원에서 팀을 알 수 있고 팀에서도 회원을 알 수 있다.

 

참조를 통한 연관관계는 언제나 단방향. 객체에는 양방향관계가 없음. 양방향을 만들고 싶으면 서로 다른방향의 단방향 2개를 만들어야함.

 

이제 JPA를 통해서 이 두개를 매핑해 보겠다.

 

//Member
@Entity
@Table(name="MEMBER")
public class Member {
    @Id
    private String id;
    @Column(name = "NAME")
    private String username;
    private Integer age;
    @ManyToOne
    @JoinColumn(name="TEAM_ID")
    private Team  team;
    public String getId() {
        return id;
    }
//TEAM
@Entity
public class Team {
    @Id
    private String id;
    private String name;
}

 

@ManyToOne과 @JoinColum(name="TEAM_ID")를 통해 연관관계를 매핑 하고 있는 것이 보인다. 

@ManyToOne: 다대일 관계라는 매핑 정보.

@JoinColum(name="TEAM_ID"):조인 컬럼은 외래키를 매핑할때 사용. name속성에 외래키 지정.

 

 

양방향 매핑관계

이번에는 회원이 팀에 접근할수있고 팀도 회원이 접근할수 있게 양방향으로 매핑을 해보겠다.

그러면 아까전모델링과 동시에 Team 객체에는 member객체를 가지고 있어야하는데 Team과 member는 일대다관계이므로 List로 member를 받는다.

db의 경우에는 처음부터 team_id 외래키 하나로 양방향 조회가 다 가능하므로 더 추가하지 않아도 된다.

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
public class Team {
    @Id
    private String id;
    private String name;
    @OneToMany(mappedBy = "team")
    private List<Member> members=new ArrayList<Member>();
}

 

따라서 팀을 저렇게 바꿔준다. 

 

연관관계의 주인(mappedby) 

자 그럼 이제 @OnetoMany에서 사용한 mappedBy를 알아보자. 객체를 양방향으로 설정하면 객체는 참조를 통해 넘어가기에 단방향 관계가 2개가 필요하다. 그에 반해 테이블은 외래키 1개로 양방향이 가능하기에 여기서 차이가 발생한다. 이러한 차이로 인해 두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리하게 하는데 이것을 연관관계의 주인 이라고 한다.

 연관관계의 주인만이 DB 연관관계와 매핑되고 외래키를 관리 할 수 있다. 반면에 주인이 아닌쪽은 읽기만 할 수 있다.

 

-주인은 mappedBy속성을 사용하지 않는다.

-주인이 아니면 mappedBy 속성을 사용해서 속성의 값으로 연관관계의 주인을 지정해야한다.

 

team과 member의 입장을 생각해보면 member.team이 연관관계의 주인이 되면 자기의 테이블에 있는 외래키만 관리하면 된다. 그러나 team.member가 연관관계의 주인이 되면 물리적으로 다른 테이블의 외래키도 관리해야한다. 효율적으로 좋지 못하다. 그래서 테이블의 외래키가 있는 곳에 연관관계의 주인이있다.. 즉 연관관계의 주인은 늘 외래키가 있는 곳이다.

 

정리하면 연관관계의 주인만 DB연관관계와 매핑되고 외래키를 관리한다. 주인이 아닌 반대편은 읽기만 가능하다.

->연관관계의 주인이 아닌곳에 생성이나 제거 코드를 넣어도 그냥 무시됨.

 

주의점

-연관관계의 주인에는 값을 입력하지 않고 주인이 아닌 곳에만 값을 입력하면 안됨

->연관관계의 주인만이 외래 키의 값을 변경할 수 있다.

->그렇다고 그 역만 해서도 좋지 않음.

->가장 안전한건 객체 관점에서 양쪽방향에 모두 값을 입력해주는것.

 

 

'Jpa' 카테고리의 다른 글

고급매핑  (0) 2021.01.10
다양한 연관관계 매핑  (0) 2021.01.10
엔티티 매핑  (0) 2021.01.09
영속성 관리  (0) 2021.01.07
JPA란?  (0) 2021.01.06