[JPA] 연관관계 매핑 - 단방향 연관관계

leehyunjon·2022년 7월 17일
0

JPA

목록 보기
6/10

연관관계

연관관계 필요성

Member와 Team이 있다.

Member는 하나의 Team에 속할 수 있다.

Member와 Team은 다대일 관계라고 하고 객체를 테이블 데이터 중심으로 모델링 했을 때, 객체와 테이블은 아래와 같다.

위 객체 연관관계에 따라 엔티티를 모델링해보면 아래와 같다.

@Entity
public class Member{
	@Id
    Long id;
    
    Long teamId
    
    String username;
}

@Entity
public class Team{
	@Id
    Long id;
    
    String name;
}

테이블 중심 모델링의 엔티티는 Member에서 연관관계를 가지는 Team을 찾기 위해서 순수 Team의 식별값을 가지고 있기 때문에 Member를 찾아서 Member가 가진 TeamId를 통해 Team을 다시 찾아야하므로 많은 비용이 사용된다.
그리고 객체지향적인 코드가 되지 못한다.

Member memeber = em.find(Member.class, 1);

Long teamId = member.getTeamId();
Team team = em.find(Team.class , teamId);

하지만 테이블 중심 모델링이 아닌 객체 지향 모델링의 엔티티는 참조를 통해 연관관계를 가지기 때문에 Member.getTeam()을 통해 Member가 속한 Team을 찾을 수 있게 된다.

@Entity
public class Member{
	@Id
    Long id;
    
    Team team;
    
    String username;
}

@Entity
public class Team{
	@Id
    Long id;
    
    String name;
}

즉, 객체지향적인 코드가 되고 참조를 통해 편리한 연관관계 조회가 가능해진다.


단방향 연관관계

참조 : https://velog.io/@conatuseus/%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84-%EB%A7%A4%ED%95%91-%EA%B8%B0%EC%B4%88-1-i3k0xuve9i

객체와 테이블의 연관관계

객체 연관관계

객체는 참조를 통해 연관관계를 가진다.

member.getTeam()을 통해 연관관계인 team을 가져올 수 있다. 하지만 team을 통해서는 소속된 member를 가져올 수 없다. 즉, 단방향 관계이다.

member -> team 조회는 가능.
team -> member 조회는 접근 가능 변수가 없다.

테이블 연관관계

테이블은 외래키를 통해 연관관계를 가진다.

어느 한쪽 테이블에서 연관관계의 외래키를 가지고 있다면 Join을 통해 서로의 테이블을 가져올 수 있다. 즉, 양방향 관계이다.

Member JOIN Team ON Member.Team_ID = Team.ID
Team JOIN Member ON Team.ID = Member.Team_ID

객체 연관관계와 테이블 연관관계 차이

테이블은 외래키로 인한 양방향 관계이고 객체는 참조로 인한 단방향 관계이다.

객체에서 서로를 참조하여 양방향으로 보이게 만들 수 있지만, 이는 양방향 관계가 아닌 서로 다른 단방향 관계 2개이다.


@ManyToOne

Member는 하나의 Team에만 속할 수 있다.
즉, Team에는 여러명의 Member가 속할 수 있다.

그렇기 때문에 여러개의 Member가 동일한 Team과 연관관계를 가질 때 Member와 Team은 다대일(N:1)의 관계를 가지게 된다.

또한 Member에서는 Team을 조회할 수 있지만, Team에서는 Member를 조회할 수 없다.

그렇기 때문에 단방향 @ManyToOne(다대일)이라고 할 수 있다.

@Entity
public class Member{
	@Id
    Long id;
    
    String username;
    
    @ManyToOne
    Team team;
}

@Entity
public class Team{
	@Id
    Long id;
    
    String name;
}

단방향 다대일 연관관계 저장

//team 저장
Team team = new Team();
team.setName("팀1");
em.persist(team);

//member 저장
Member member = new Member();
member.setUserName("멤버1");
member.setTeam(team);	//단방향 연관관계 설정
em.persist(member);

Member에서만 Team을 참조가능한 단방향 관계이기 때문에 Member에만 Team을 설정해주면 된다.

단방향 다대일 객체 그래프 탐색

Member member = em.find(Member.class, 1);

Team team = member.getTeam();
String teamName = member.getTeam().getName();

단방향 다대일 연관관계 수정

Team team2 = new Team();
team2.setName("팀2");
em.persist(team2);

member.setTeam(team2);	//멤버1에 새로운 팀2 설정

@ManyToOne 설정

@ManyToOne이란 엔티티에서 참조하는 객체와의 관계를 설정할때 사용하는 어노테이션이다.

  • fetch : 글로벌 패치 전략을 설정한다. (추후 설명)

    • FetchType.EAGER : 연관관계의 객체를 사용하지 않아도 연관 객체를 불러올때 함께 불러옴.(default)
    • FetchType.LAZY : 연관관계의 객체를 실제로 사용하는 순간에 실제 객체를 불러옴.(지연로딩)
  • cascade : 영속성 전이 기능 (추후 설명)

@JoinColumn 설정

@JoinColumn은 외래키를 매핑할 때 사용하는 어노테이션이다.
@JoinColumn어노테이션은 생략이 가능하다.

  • name : 매핑할 외래키 이름 (default : "필드명"+"_"+"참조 테이블 기본키 컬럼명")
profile
내 꿈은 좋은 개발자

0개의 댓글