다중성
N:1 - 실무에서 권장, N에 외래키가 있다.
1:N - 실무에서 권장하지 않는 방식, 1에 외래키가 있다.
1:1 - 어느 곳이나 외래키를 가질 수 있다.
N:M
연관관계의 주인 : 두 객체의 연관관계 중 하나를 정해서 데이터베이스의 외래키를 관리
일반적으로 다(M, many) 방향에서 외래키를 가지고 있는 것이 효율적이기 때문에 Many 방향을 연관관계의 주인으로 선택한다.
연관관계의 주인이 아닌 클래스 (1, one)는 외래키를 변경 불가, 읽기만 가능
Team : Member = 1 : N
외래키는 N인 Member가 team_id 컬럼을 가진다.
외래키를 가진 방향을 연관관계의 주인으로 지정해두는 것이 효율적이며
Member class가 외래키를 가지고 있기 때문에 연관관계의 주인이다.
연관관계의 주인 클래스 Member에는 mappedBy 속성을 사용하지 않는다.
One(1) 방향인 Team은 외래키를 변경할 수 없고 읽기만 가능하다.
연관관계의 주인 클래스가 아닌 반대 클래스 Team은 mappedBy 속성을 사용한다.
(양방향 관계일 경우 사용, 단방향에서는 x)
N:1 단방향 : Team에는 Member 클래스 필드가 없다.
@Entity
@Getter
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
@Entity
@Getter
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
}
N:1 양방향 : Team에도 Member 클래스 필드가 있다.
연관관계의 주인 반대방향에 mappedBy 필요, 두 방향 모두 연관관계 편의 메서드 적용
@Entity
@Getter
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
public void setTeam(Team team) {
this.team = team;
if (!team.getMembers().contains(this)) {
team.getMembers().add(this);
}
}
}
@Entity
@Getter
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<Member>();
public void addMember(Member member) {
this.members.add(member);
if (member.getTeam() != this) {
member.setTeam(this);
}
}
}
1:1 연관관계
Member : Locker = 1:1
1:1 단방향 - 주 테이블이 외래키를 가지는 경우
1:1 단방향 - 대상 테이블이 외래키를 가지는 경우
1:1 양방향
1:1 단방향 - 주 테이블이 외래키를 가지는 경우
- 주 객체가 대상 객체를 참조하는 것처럼 주 테이블에 외래키를 두고 대상 테이블을 찾는다. (객체 지향적)
- JPA 매핑이 편하고 주 테이블만 조회해도 대상 테이블의 데이터 확인 가능하다.
- 대상 테이블 조회 시 대상 테이블에 값이 없다면 null 허용 => 참조 무결성 위반 가능
Member 클래스가 Locker 클래스를 가지고 있다.
외래키는 기본적으로 중복이 허용되기 때문에 데이터베이스에서 LOCKER_ID 외래키에 유니크 제약 조건을 추가해야 한다.
@Entity
@Getter
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
}
@Entity
@Getter
public class Locker {
@Id @GeneratedValue
@Column(name = "LOCKER_ID")
private Long id;
private String name;
}
1:1 단방향 - 대상 테이블이 외래키를 가지는 경우
- 대상 테이블 (Locker)에 외래키가 있으며 Member 클래스가 Locker 필드를 가지는 단방향 관계는 기본적으로 JPA에서 지원 x
- 대상 테이블 (Locker)에 외래키가 있으며 1:1 단방향을 이루기 위해서는 Locker 클래스가 Member 필드를 가지도록 방향을 변경하거나
- 양방향 관계로 만든 뒤 Locker를 연관관계의 주인 (외래키를 관리하는 테이블)로 설계한다.
Member 클래스가 Locker 클래스를 가지고 있다.
외래키는 기본적으로 중복이 허용되기 때문에 데이터베이스에서 LOCKER_ID 외래키에 유니크 제약 조건을 추가해야 한다.
'Java & Spring' 카테고리의 다른 글
| QueryDSL (0) | 2026.04.30 |
|---|---|
| [Java] Map 정렬 (0) | 2026.03.03 |
| [Spring] ResponseEntity (0) | 2026.02.22 |
| [Servlet] WebSocket (0) | 2026.02.16 |
| [Spring] Security (0) | 2026.02.15 |