[JPA] 연관관계 매핑 기초

·2024년 4월 14일
0

JPA

목록 보기
3/17
post-thumbnail

💡 단방향 연관관계

📗단방향 연관관계 설계

1. 객체 연관관계 사용

📌요구사항

  • 회원과 팀 엔티티가 있다.
  • 회원은 하나의 팀에만 소속될 수 있고, 하나의 팀에는 여러명의 회원이 소속 될 수 있다.
  • 회원과 팀은 다대일 관계다.

2. 객체의 참조와 테이블의 외래 키를 매핑

Member 엔티티

@Entity
public class Member{

	@Id @GeneratedValue
    private Long id;
    
    @Column(name="USERNAME")
    private String name;
    private int age;
    
    @ManyToOne
    @JoinColum(name="TEAM_ID")
    private Team team;
}

Team 엔티티

@Entity
public class Team{

	@Id @GeneratedValue
    @Column(name="TEAM_ID")
    private Long id;
    
    private String name;
}
  • @ManyToOne : 다대일 관계임을 알려줌.
    • 하나의 팀에 여러멤버가 소속되므로 멤버가 N, 팀이 1이다.
  • @JoinColum : 조인해야하는 컬럼을 알려줌.
    • TEAM_ID 컬럼과 조인해야하므로 name="TEAM_ID" 작성

3. 연관관계 저장 및 조회

//팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
    
//회원 저장
Member member = new Member();
member.setName("member1");
member.setTeam(team);	//단방향 연관관계 설정. 참조 저장
em.persist(member);
    
//조회
Member findMember = em.find(Member.class, member.getId());
    
//참조를 사용해서 연관관계 조회
Team findTeam = findMember.getTeam();

4. 연관관계 수정

//팀 저장
Team teamB = new Team();
teamB.setName("TeamB");
em.persist(teamB);

//회원1에 새로운 팀B 설정
member.setTeam(teamB);

💡양방향 연관관계

📗양방향 연관관계 설계

1. 양방향 객체 연관관계 사용

  • 테이블의 연관관계에는 방향이란게 없다.
    • FK 하나로 서로의 연관을 모두 알수 있기 때문.
  • 하지만 객체 연관관계에서는 Member에서 Team으로 갈 수 있지만, Team에서 Member로 갈수 있는 방법이 없다.
    ➡️Team에서 Member로 갈 수 있도록 Team에 리스트를 넣어줘야한다.

2. 객체의 양방향 매핑

Member 엔티티

@Entity
public class Member{

	@Id @GeneratedValue
    private Long id;
    
    @Column(name="USERNAME")
    private String name;
    private int age;
    
    @ManyToOne
    @JoinColum(name="TEAM_ID")
    private Team team;
}
  • Member 엔티티는 단방향 매핑때와 동일. 달라진게 없다.

Team 엔티티

@Entity
public class Team{

	@Id @GeneratedValue
    @Column(name="TEAM_ID")
    private Long id;
    
    private String name;
    
    @OneToMany(mappedBy = "team")
    List<Member> members = new ArrayList<Member>();
}
  • @OneToMany : 일대다 관계임을 알려줌.
    • Member에서 Team으로 가는게 다대일이면 Team에서 Member로 가는건 일대다
  • mappedBy : 무엇과 조인이 걸려있는지(매핑되었는지 알려줌.)
    • Member의 JoinColumn되어 있는 객체를 적어주면 된다.

양방향 조회

//team 조회
Team findTeam = em.find(Team.class, team.getId());

//역방향 조회
int memberSize = findTeam.getMembers().size();

💡연관관계의 주인과 mappedBy

객체와 테이블간에 연관관계 맺는 차이를 이해해야 mappedBy를 이해하기 쉽다.

📗객체와 테이블이 관계를 맺는 차이

  • 객체 연관관계 = 2개
    • 회원 -> 팀 연관관계 1개(List member. 단방향)
    • 팀 -> 회원 연관관계 1개(Team team. 단방향)
  • 테이블 연관관계 = 1개
    • 회원 <-> 팀 연관관계 1개(FK. 양방향)

➡️객체의 양방향 관계는 서로 다른 단방향 관계 2개다!

즉, 테이블은 외래키 하나로 두 테이블의 연관관계를 정리하지만 객체의 양방향 관계는 단방향관계 2개이므로 둘 중 한개의 연관관계로 외래키를 관리해야한다.
➡️여기서 결정한 한개의 연관관계가 바로 연관관계의 주인이 되는 것!

📗연관관계의 주인

양방향 매핑 규칙

  • 객체의 두 관계중 하나를 연관관계의 주인으로 지정
  • 연관관계의 주인만이 외래 키를 관리(등록, 수정)
  • 주인이 아닌쪽은 읽기만 가능
  • 주인은 mappedBy 속성 사용 불가
  • 주인이 아니면 mappedBy 속성으로 주인 지정

그렇다면, 누구를 주인으로?

➡️외래키가 있는 곳을 주인으로 정해라

  • 위의 연관관계에서는 Member.team이 연관관계의 주인이다
    • 테이블 연관관계에서 Member테이블에 FK가 있으니까!

양방향 연관관계 예시

Member 엔티티

@Entity
public class Member{

	@Id @GeneratedValue
    private Long id;
    
    @Column(name="USERNAME")
    private String name;
    private int age;
    
    @ManyToOne
    @JoinColum(name="TEAM_ID")
    private Team team;
    
    ...
    //연관관계 편의 메서드 작성
    public void changeTeam(Team team){
    	this.team = team;
        team.getMember().add(this);
    }
}

Team 엔티티

@Entity
public class Team{

	@Id @GeneratedValue
    @Column(name="TEAM_ID")
    private Long id;
    
    private String name;
    
    @OneToMany(mappedBy = "team")
    List<Member> members = new ArrayList<Member>();
}

실행 코드

	//team 저장
    Team team = new team();
    team.setName("teamA");
    em.persist(team);
    
    //MEMBER 저장
    Member member = new Member();
    member.setName("memberA");
    
    //연관관계 편의 메서드를 사용해서 값 저장
    member.changeTeam(team);	
    em.persist

📌양방향 매핑 정리

  • 단방향 매핑만으로도 이미 연관관계 매핑은 종료
  • 단방향 매핑을 잘하고 양방향은 필요할 때 추가해도 됨
  • 연관관계의 주인은 외래 키의 위치를 기준으로 정해야한다
profile
백엔드 개발자를 꿈꿉니다 / 이전 블로그 : https://po-dadak.tistory.com/category

0개의 댓글

관련 채용 정보