JAVA

[JAVA] JPA 연관관계 매핑( 단방향 )

응디 2021. 11. 16. 17:29

핵심 : 객체지향스럽게 매핑하는 방법

 

예제 시나리오
- 회원과 팀이 있다.
- 회원은 하나의 팀에만 소속될 수 있다.
- 회원(N)과 팀(1)은 다대일 관계이다.

 

1. 객체를 테이블에 맞추어 모델링( 참조 대신 외래키를 그대로 가져와 사용한다. )

 

Member.java ( teamId 주목 )

@Entity
public class Member {
    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    @Column(name = "USERNAME")
    private String username;

    @Column(name = "TEAM_ID")
    private Long teamId;

}

 

JpaMain.java

package hellojpa;

import org.hibernate.boot.model.source.internal.hbm.XmlElementMetadata;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.util.List;

public class JpaMain {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try{
            Team team = new Team();
            team.setName("TeamA");
            em.persist(team);

            Member member = new Member();
            member.setUsername("member1");
            // 관계형 데이터베이스 형식으로 엔티티를 구성하면 아래처럼 복잡함이 생김
            member.setTeamId(team.getId());
            em.persist(member);

            // 연관관계를 사용하지 않을 시 조회를 할 때도 복잡해진다.
            Member findMember = em.find(Member.class, member.getId());
            // 팀이 궁금하다면?? 바로 알수 없음 => teamId를 가져와서 사용해야함
            Long findTeamId = findMember.getTeamId();
            Team findTeam = em.find(Team.class, findTeamId);


            tx.commit(); // commit을 실행하면서 쿼리를 DB에 날림
        }catch (Exception e){
            //중요!! 문제가 발생하면 rollback
            tx.rollback();
        }finally {
            em.close();
        }
        emf.close();

    }
}

 

※ 만약 연관관계를 사용 하지 않는 다면 위와같이 member의 team을 가져오는데 계속 꺼내와야하는 불편함이 있다.

→ 이는 객체 지향적 코드가 아니다!

 


2. 단방향 연관관계 매핑

 

객체 연관 관계

  • 회원객체 Member는 Member.team으로 팀객체와 연관관계를 맺는다.
  • 회원 객체와 팀 객체는 단방향 관계
  • 회원은 Member.team을 통해 회원의 팀을 알 수 있지만 , 팀은 소속된 회원을 알 수 없다. 

테이블 연관 관계

  • 회원 테이블은 team_id 외래 키로 팀 테이블과 연관관계를 맺는다.
  • 회원 테이블과 팀 테이블은 양방향 관계 
  • 서로 외래키를 통해 회원은 팀을 팀은 회원을 조회 할 수 있다.

 

객체와 테이블 연관 관계의 가장 큰 차이점?

테이블은 양방향 관계 이지만 객체는 단방향 사실 관계로만 이루어져 있다!

→ 객체를 양방향으로 참조 하려면 단방향 연관관계를 2개를 만들어야함