연관관계 다중성
다중성 종류
1대1 관계 : One To One
N대 1관계 : Many To One
1대 N 관계 : One To Many
N대 M 관계 : Many To Many
1. 1대 1 관계
@OneToOne 애노테이션은 1대1 관계를 맺어주는 역할을 한다
고객 Entity와 음식 Entity가 1대1관계라 가정하여 관계를 맺어보자
단방향관계
- 외래 키의 주인 정하기
- Entity에서 외래 키의 주인은 일반적으로 N(다)의 관계인 Entity 이지만 1 대 1 관계에서는 외래 키의 주인을 직접 지정해야함
- 외래 키 주인만이 외래 키 를 등록, 수정, 삭제할 수 있으며, 주인이 아닌 쪽은 오직 외래 키를 읽기만 가능
- @JoinColumn()은 외래 키의 주인이 활용하는 애너테이션입니다.
- 컬럼명, null 여부, unique 여부 등을 지정할 수 있습니다.

음식 Entity가 외래키의 주인인 경우
음식
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToOne
@JoinColumn(name = "user_id")
private User user;
}
고객
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
고객 Entity가 외래키의 주인인 경우

고객에
@OneToOne
@JoinColumn(name = "food_id")
private Food food;
이렇게 적어주면 된다
양방향 관계
- 양방향 설정
- 양방향 관계에서 외래 키의 주인을 지정해 줄 때 mappedBy 옵션을 사용
- mappedBy의 속성값은 외래 키의 주인인 상대 Entity의 필드명을 의미
- 관계 설정 방법에 대해 정리
- 단방향이라면 외래 키의 주인만 상대 Entity 타입의 필드를 가지면서 @JoinColumn()을 활용하여 외래 키의 속성을 설정해주면됩니다.
- 양방향이라면 외래 키의 주인은 상대 Entity 타입의 필드를 가지면서 @JoinColumn()을 활용하여 외래 키의 속성을 설정을 해줍니다.
- 그리고 상대 Entity는 외래 키의 주인 Entity 타입의 필드를 가지면서 mappedBy 옵션을 사용하여 속성 값으로 외래 키의 주인 Entity에 선언된 @JoinColumn()으로 설정되고 있는 필드명을 넣어주면 됩니다.

음식 Entity가 외래 키의 주인인 경우!
음식
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToOne
@JoinColumn(name = "user_id")
private User user;
}
고객
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(mappedBy = "user")
private Food food;
}
고객 Entity가 외래키의 주인인 경우
음식에서
@OneToOne(mappedBy = "food")
private User user;
고객에서
@OneToOne
@JoinColumn(name = "food_id")
private Food food;
이렇게 해주면 된다
2. N대 1관계
@ManyToOne 애너테이션은 N대 1관계를 맺어주는 역할
음식 Entity와 고객 Entity가 N대 1관계라 가정
단방향 관계
.

음식 Entity가 N의 관계로 외래 키의 주인
음식
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
고객
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
양방향 관계일 경우

음식
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
고객
@OneToMany(mappedBy = "user")
private List<Food> foodList = new ArrayList<>();
3. 1대 N 관계
@OneToMany 애너테이션은 1대 N관계를 맺어주는 역할
단방향 관계

- 외래 키를 관리하는 주인은 음식 Entity이지만 실제 외래 키는 고객 Entity가 가지고 있습니다.
- 1 : N에서 N 관계의 테이블이 외래 키를 가질 수 있기 때문에 외래 키는 N 관계인 users 테이블에 외래 키 컬럼을 만들어 추가하지만 외래 키의 주인인 음식 Entity를 통해 관리
음식
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToMany
@JoinColumn(name = "food_id") // users 테이블에 food_id 컬럼
private List<User> userList = new ArrayList<>();
}
고객
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
외래 키를 음식 Entity가 직접 가질 수 있다면 INSERT 발생 시 한번에 처리할 수 있지만 실제 DB에서 외래 키를 고객 테이블이 가지고 있기 때문에 추가적인 UPDATE가 발생된다는 단점이 존재
1 대 N 관계에서는 일반적으로 양방향 관계가 존재하지 않는다
4. N대 M 관계
@ManyToMany 애너테이션은 N대 M 관계를 맺어주는 역할
단방향 관계

N : M 관계를 풀어내기 위해 중간 테이블(orders)을 생성하여 사용
음식 Entity가 외래 키의 주인
음식
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToMany
@JoinTable(name = "orders", // 중간 테이블 생성
joinColumns = @JoinColumn(name = "food_id"), // 현재 위치인 Food Entity 에서 중간 테이블로 조인할 컬럼 설정
inverseJoinColumns = @JoinColumn(name = "user_id")) // 반대 위치인 User Entity 에서 중간 테이블로 조인할 컬럼 설정
private List<User> userList = new ArrayList<>();
}
고객
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
생성되는 중간 테이블을 컨트롤하기 어렵기 때문에 추후에 중간 테이블의 변경이 발생할 경우
문제가 발생할 가능성이 있습니다.
양방향 관계

음식 Entity가 외래 키의 주인
음식
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToMany
@JoinTable(name = "orders", // 중간 테이블 생성
joinColumns = @JoinColumn(name = "food_id"), // 현재 위치인 Food Entity 에서 중간 테이블로 조인할 컬럼 설정
inverseJoinColumns = @JoinColumn(name = "user_id")) // 반대 위치인 User Entity 에서 중간 테이블로 조인할 컬럼 설정
private List<User> userList = new ArrayList<>();
}
고객
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(mappedBy = "userList")
private List<Food> foodList = new ArrayList<>();
}
반대 방향인 고객 Entity에 @ManyToMany 로 음식 Entity를 연결하고 mappedBy 옵션을 설정하여 외래 키의 주인을 설정하면 양방향 관계 맺음이 가능합니다.
'TIL' 카테고리의 다른 글
| TIL 240529 회원기능 설계, JWT 로그인 인증처리(Filter) (0) | 2024.05.30 |
|---|---|
| 240528 MVC 패턴 (0) | 2024.05.29 |
| TIL 240524 Entity 연관관계 (0) | 2024.05.27 |
| TIL 240523 JDBC (0) | 2024.05.24 |
| TIL 240522 NAVER Open API (0) | 2024.05.23 |