공부하면서 알게된 1:N, 1:1, N:M 관계에서 단방향과 양방향 매핑을 어떻게 설정하고 각각의 장단점은 무엇인지 정리해보았다. 아직도 잘 이해가 되지않지만 정리하면서 또 복습해보자
@Entity
public class Post {
@Id @GeneratedValue
private Long id;
@OneToMany
@JoinColumn(name = "post_id") // Comment 테이블에 FK를 생성
private List<Comment> comments = new ArrayList<>();
}
특징
장단점
@Entity
public class Post {
@Id @GeneratedValue
private Long id;
@OneToMany(mappedBy = "post")
private List<Comment> comments = new ArrayList<>();
}
@Entity
public class Comment {
@Id @GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "post_id")
private Post post;
}
mappedBy를 사용해 연관 관계의 주인을 Comment로 설정
Post는 단순히 관계를 조회하는 역할(Read-Only)
장점
단점
@Entity
public class User {
@Id @GeneratedValue
private Long id;
@OneToOne
@JoinColumn(name = "profile_id") // User 테이블에 FK 생성
private Profile profile;
}
@Entity
public class Profile {
@Id @GeneratedValue
private Long id;
}
User 엔티티가 Profile을 참조하며, 외래 키는 User 테이블에 생성
@Entity
public class User {
@Id @GeneratedValue
private Long id;
@OneToOne(mappedBy = "user")
private Profile profile;
}
@Entity
public class Profile {
@Id @GeneratedValue
private Long id;
@OneToOne
@JoinColumn(name = "user_id") // Profile 테이블에 FK 생성
private User user;
}
mappedBy를 사용해 관계의 주인을 Profile로 설정
@Entity
public class Student {
@Id @GeneratedValue
private Long id;
@ManyToMany
@JoinTable(name = "student_class",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "class_id"))
private List<Class> classes = new ArrayList<>();
}
@Entity
public class Class {
@Id @GeneratedValue
private Long id;
}
@JoinTable을 사용해 중간 테이블(student_class)을 생성
@Entity
public class Student {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "student")
private List<Enrollment> enrollments = new ArrayList<>();
}
@Entity
public class Class {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "clazz")
private List<Enrollment> enrollments = new ArrayList<>();
}
@Entity
public class Enrollment {
@Id @GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "student_id")
private Student student;
@ManyToOne
@JoinColumn(name = "class_id")
private Class clazz;
private LocalDateTime enrolledAt; // 등록 일자
private String status; // 상태 (예: "진행 중", "완료")
}
결론적으로,
기본적인 N:M 매핑은 간단하지만 실무에서는 중간 엔티티를 활용한 방식이 훨씬 유리하다.
설계 초기 단계에서 확장성과 유지보수성을 고려해 중간 엔티티를 사용하는 것이 좋다.