@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId; // 사용자의 고유 ID
private String username; // 사용자 이름
@OneToOne(mappedBy = "user") // 필드가 반대측 프로필 클래스의 'user' 필드를 참조
private Profile profile; // 사용자와 연결된 프로필
}
@Entity
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long profileId; // 프로필의 고유 ID
private String bio; // 프로필의 정보
@OneToOne // 각각의 프로필은 하나의 사용자에 연결됨
@JoinColumn(name = "user_id") // 외래 키를 설정하여 사용자와 연결
private User user; // 이 프로필과 연결된 사용자
}
@Entity
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long courseId; // 수업의 고유 ID
private String title; // 수업 제목
@OneToMany(mappedBy = "course") // 반대측 학생 클래스의 'course' 필드로 매핑
private List<Student> students; // 이 수업을 수강하는 학생 목록
}
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long studentId; // 학생의 고유 ID
private String name; // 학생 이름
@ManyToOne // 여러 학생이 하나의 수업에 속할 수 있는 관계
@JoinColumn(name = "course_id") // 외래 키를 설정하여 수업과 연결
private Course course; // 학생이 속한 수업
}
연관관계는 단방향이거나 양방향일 수 있으며 동작을 명확히 하기 위해 mappedBy나 조인 테이블 설정을 통해 관계를 구체적으로 설정할 수 있다.
양방향 관계에서 외래 키가 위치하는 N측의 필드를 지정하는 역할
@OneToMany(mappedBy = "customer")
private List<Order> orders;
예를 들어, Customer와 Order의 관계에서 Order 클래스의 customer 필드가 이 관계의 주체라는 것을 의미한다.
즉, Customer 클래스는 여러 Order를 참조할 수 있지만, customer_id 필드를 통해서만 참조 가능함
join 테이블은 다대다 관계를 구현할 때 중간 테이블을 생성하여 관련된 투 테이블의 관계를 관리하는 방법이다.

@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long studentId;
private String name;
@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"), // 학생 외래 키
inverseJoinColumns = @JoinColumn(name = "course_id") // 수업 외래 키
)
private List<Course> courses;
}
@Entity
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long courseId;
private String title;
@ManyToMany(mappedBy = "courses")
private List<Student> students;
}
@ManyToOne(fetch = FetchType.EAGER) // 즉시 로드
@JoinColumn(name = "department_id")
@OneToMany(mappedBy = "department", fetch = FetchType.LAZY) // 지연 로드
private List<Employee> employees;
일반적으로 LAZY 로딩이 성능 측면에서 유리하지만 필요한 경우에 따라 EAGER 로딩을 고려할 수 있다.
JPA나 하이버네이트를 사용할 때 발생하는 성능 문제로, 주로 LAZY 로딩에서 발생
데이터를 여러 부분으로 나누어 필요한 부분만 조인하여 전체 성능을 향상
SELECT d FROM Department d JOIN FETCH d.employees
단일 쿼리로 필요한 모든 데이터를 가져온다
필요한 연관관계를 미리 정의하고 로드
@EntityGraph(attributePaths = {"employees"})
List<Department> findAll();
한 번에 데이터 세트를 얼마나 로드할지 설정하여 성능개선
@OneToMany(mappedBy = "department")
@BatchSize(size = 10) // 한 번에 10개씩 로드
private List<Employee> employees;
위에서 설명함
필요한 데이터만 선택적으로 가져오는 방법
전체 엔티리를 불러오는 대신 DTO(Data Transfer Object)를 사용하여 필요한 필드만 로드한다.
public class CourseDTO {
private String title;
public CourseDTO(String title) {
this.title = title;
}
}
쿼리
SELECT new CourseDTO(c.title) FROM Course c
연관관계에서 부모 엔티티의 상태변화를 자식 엔티티에 전이되도록 설정
정답은 없고, 적재적소에 최적의 방식을 채택하여 성능향상을 하는것이 중요
안녕하세요! 개발자 준비하시는 분이나 현업에 종사하고 계신 분들만 할 수 있는 시급 25달러~51달러 LLM 평가 부업 공유합니다~ 제 블로그에 자세하게 써놓았으니 관심있으시면 한 번 읽어봐주세요 :)