연관관계 맵핑1(단방향 연관관계)

Mina Park·2022년 8월 29일
0

1. 연관관계의 필요성

  • 테이블 구조에 맞춘 객체 모델링(외래키 사용 not 참조)
@Entity
public class MemberMapping {

    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

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

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

    //...getter, setter
}
@Entity
public class TeamMapping {

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;

    private String name;

    //...getter, setter
}
 	//팀 저장
 	TeamMapping team = new TeamMapping();
    team.setName("teamA");
    em.persist(team);

	//멤버 저장
    MemberMapping member = new MemberMapping();
    member.setUsername("member1");
    member.setTeamId(team.getId()); //외래키 식별자를 직접 저장
    em.persist(member);
    
    //조회
    MemberMapping findMember = em.find(MemberMapping.class, member.getId());
    Long findTeamId = findMember.getTeamId();
    TeamMapping findTeam = em.find(TeamMapping.class, findTeamId);

📌 객체를 테이블에 맞춰 모델링할 경우, 객체지향적으로 참조를 사용하여 연관 객체 탐색이 불가



2. 순수한 객체 연관관계

  • 객체 지향 모델링
@Entity
public class MemberMapping {

    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

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

	private TeamMapping team; //팀의 참조 보관

    //...getter, setter
}
@Entity
public class TeamMapping {

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;

    private String name;

    //...getter, setter
}
 	//팀 저장
 	TeamMapping team = new TeamMapping();
    team.setName("teamA");

	//멤버 저장
    MemberMapping member = new MemberMapping();
    member.setUsername("member1");
    
    member.setTeam(team); 
    
    //조회
    TeamMapping findTeam = member.getTeam(); 

📌 참조를 사용한 연관관계 탐색을 "객체 그래프 탐색"이라고 함



3. 연관관계 맵핑

@Entity
public class MemberMapping {

    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

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

	@ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private TeamMapping team;

    //...getter, setter
}
@Entity
public class TeamMapping {

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;

    private String name;

    //...getter, setter
}
  • 어노테이션
    • @ManyToOne: 다대일(N:1) 맵핑 정보 명시(neccessary)
    • @JoinColumn(name="TEAM_ID"): 외래키 맵핑시 사용(optional)
      • 생략시 기본전략 사용: 필드명+_+참조하는 테이블의 기본키 컬럼명
      • Ex) teamMapping_TEAM_ID


4. 연관관계 사용 CRUD 예시

1) 등록

 	//팀 저장
 	TeamMapping team = new TeamMapping();
    team.setName("teamA");
    em.persist(team);

	//멤버1 저장
    MemberMapping member1= new MemberMapping();
    member.setUsername("member1");
    member.setTeam(team); //연관관계 설정: member1 -> team
    em.persist(member1);
    
   //멤버2 저장
    MemberMapping member2 = new MemberMapping();
    member.setUsername("member2");
    member.setTeam(team); //연관관계 설정: member2 -> team
    em.persist(member2);

🚫 JPA에서 엔티티 저장시 연관된 모든 엔티티는 영속 상태!!!

2) 조회

  • 연관관계가 있는 엔티티 조회 방법
    • 객체 그래프 탐색(연관관계 사용 조회)
	MemberMapping findMember = em.find(MemberMapping.class, member.getId());
    TeamMapping findTeam = findMember.getTeam();
  • 객체지향 쿼리 사용(JPQL)

3) 수정

  • 참조하는 대상만 변경 => 트랜잭션 커밋시 플러시 => 변경 감지 => 변경사항 업데이트 쿼리
	MemberMapping findMember = em.find(MemberMapping.class, member.getId());
    
	TeamMapping newTeam = em.find(TeamMapping.class, 100L);
	findMember.setTeam(newTeam);

4) 연관관계 제거

  • 연관관계 null
	MemberMapping findMember = em.find(MemberMapping.class, member.getId());
	findMember.setTeam(null);

5) 연관된 엔티티 삭제

  • 기존 연관관계 先제거 => 삭제
	MemberMapping findMember = em.find(MemberMapping.class, member.getId());
	findMember.setTeam(null); //연관관계 제거
    em.remove(team); //팀 삭제

0개의 댓글