JPA 연관 관계
특징
데이터베이스 외래 키 하나로 두 테이블이 관계를 맺는다.
엔티티는 양방향으로 연관 관계를 맺으면 연관 관계를 관리하는 포인트는 2곳이 된다.
필수 지식
@JoinColumn
외래 키(FK)를 매핑할 때 사용된다.
name; 매핑할 외래 키 이름; default 필드명 + _ + 참조하는 테이블의 PK 컬럼명
아래와 같이 회원 Entity를 선언하고 팀 Entity과 연관 관계를 맺었는데, @JoinColumn만 선언하고 name 필드 값을 선언 하지 않으면 team_TEAM_ID
로 선언된 외래 키(FK)를 찾고 매핑한다.
public class Member {
@Id
@Column(name = "user_id")
private String id;
private String name;
@ManyToOne
@JoinColumn
private Team team;
}
public class Team {
@Id
@Column(name = "team_id")
private UUID id;
@Column(name = "team_name")
private String name;
}
연관 관계 매핑
객체 연관 관계; 회원 객체의 Memeber.team 필드 사용
테이블 연관 관계; 회원 테이블의 MEMBER.TEAM_ID 외래 키 컬럼 사용
Member.team과 MEMBER.TEAM_ID를 매핑하는 것이 연관관계 매핑이다.
연관 관계를 사용한 등록(Create)/조회(Read)/수정(Update)/삭제(Delete)
Create
팀 엔티티를 저장하고 회원 엔티티가 팀 엔티티의 Team.id(FK)를 참조하고 저장했다. JPA는 참조한 팀의 식별자(Team.id)를 외래 키로 사용해서 적절한 Insert Query를 생성한다.
Team team = new Team();
team.setId("1234-1234-1234-1234");
team.setName("Order Of The Phoenix");
em.persist(team);
Member m1 = new Member();
m1.setId("SB");
m1.setName("Sirius Black");
m1.setTeam(team); // Memeber가 Team을 참조했다.
em.persist(m1);
다대일 [N:1]
임직원은 팀에 속하며, 팀은 임직원으로 구성되어 있다.
단방향
@JoinColumn(name = "TEAM_ID")
를 이용해서 Employee.team
필드를 employee 테이블의 TEAM_ID 외래 키(FK) 컬럼과 매핑했다. 따라서 Employee.team 필드로 employee 테이블의 TEAM_ID 외래 키를 관리한다.
@Entity
public class Employee {
@Id
private String id;
@ManyToOne
@JoinColumn(name = "team_id")
private Team team;
}
@Entity
public class Team {
@Id
private String id;
private String teamName;
}
양방향
실선이 연관 관계의 주인(Employee.team)이고 점선(Team.members)은 연관 관계의 주인이 아니다.
@Entity
public class Employee {
@Id
private String id;
@ManyToOne
@JoinColumn(name = "team_id")
private Team team;
}
@Entity
public class Team {
@Id
private String id;
private String teamName;
@OneToMany(mappedBy = "team")
List<Employee> members;
}
일대다 [1:N]
팀은 여러 명의 임직원을 가진다.
단방향
Team.emplyeese로 emplyee 테이블의 team_id 외래 키를 관리한다. 보통 자신이 매핑한 테이블(team)에 외래 키가 있고 해당하는 외래 키를 관리하는데, 이 매핑은 반대쪽 테이블(emplyee)에 있는 외래 키를 관리한다. 그럴 수 밖에 없는 것이 일대다 관계에서는 외래 키가 항상! 다(N)쪽 테이블에 있다.
일대다 단방향 매핑에서는 꼭! @JoinColumn를 명시 해줘야 한다. 그렇지 않다면, JPA가 자동으로 연관 관계를 관리하는 JOIN 테이블 전략을 기본적으로 사용해서 매핑한다.
public class Team {
@Id
@Column(name = "team_id")
private UUID id;
@OneToMany
@JoinColumn(name = "team_id")
List<Employee> employeese;
}
public class Employee {
@Id
@Column(name = "user_id")
private String id;
private String password;
}
Employee a = new Employee();
Employee b = new Employee();
Team dataplatform = new Team();
// Setter를 이용해서 필요한 모든 값을 할당 했다고 가정
employeeRepository.save(a); // INSERT a
employeeRepository.save(b); // INSERT b
teamRepository.save(dataplatform); // INSERT dataplatform and UPDATE a.team_id
일대다 관계에서는 외래 키(FK)가 자신의 테이블이 아닌 다른 테이블에 있다는 점이다. 본인 테이블에 외래 키가 있으면 Entity의 저장과 연관 관계 처리를 Insert Query 한번으로 끝낼 수 있지만, 다른 테이블에 외래 키가 있으면 연관관계 처리를 위한 UPDATE 쿼리를 추가 실행해야 한다는 단점을 가진다.
일대일 [1:1]
양쪽이 서로 하나의 관계만 가진다. 예를 들어 회원은 하나의 장바구니를 부여 받고 사용하고 하나의 장바구니도 하나의 회원에 속해진다.
특징
일대일 관계는 그 반대로 일대일 관계이다.