2025년 11월 10일 월요일 (111일차)

Jeonghoon·2025년 11월 10일

jeonghoon's Study

목록 보기
114/128

☕ JPA 연관관계 & 커스텀 쿼리 정리


🧩 [ JPA 연관관계 (Entity Relationship) ]

🔗 개념

  • 여러 Entity 간의 참조 관계를 관리하는 기능
  • 객체지향의 연관 관계를 DB의 FK 관계로 매핑
구분설명
단방향한 엔티티가 다른 엔티티만 참조
양방향서로가 서로의 엔티티를 참조

🔹 [ 단방향 관계 ]

  • 하위 엔티티가 상위 엔티티를 참조하는 구조
  • 다수의 하위(FK)가 하나의 상위(PK)를 참조 (ManyToOne)

📘 예시 코드

@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "FK_필드명")
private ParentEntity parent;

🔸 [ 양방향 관계 ]

  • 상위 엔티티가 하위 엔티티를 참조하는 구조
  • 하나의 PK가 여러 FK를 참조 (OneToMany)

📘 예시 코드

@OneToMany(mappedBy = "parent")
@ToString.Exclude       // 순환 참조 방지
@Builder.Default        // 빌더 패턴 사용 시 초기값 유지
private List<ChildEntity> childList = new ArrayList<>();

💡 Tip:
mappedBy참조할 변수명을 명시하며, FK의 주인은 @ManyToOne 쪽이다.


⚙️ [ 영속성 제약조건 ]

🔁 [ Cascade (연쇄 작업 설정) ]

옵션설명
CascadeType.ALL부모가 삭제/수정/저장되면, 자식도 같이 처리
CascadeType.PERSIST부모 저장 시, 자식도 함께 저장
CascadeType.MERGE부모 수정 시, 자식도 함께 수정
CascadeType.REMOVE부모 삭제 시, 자식도 함께 삭제
CascadeType.REFRESH부모 재호출 시, 자식도 재호출
CascadeType.DETACH부모 영속 해제 시, 자식도 함께 영속 해제

⚠️ 주의: CascadeType.ALL은 편리하지만, 실수로 모든 자식이 삭제될 수 있으므로 신중히 사용해야 한다.


🔍 [ Fetch (조회 전략) ]

  • 부모/자식 엔티티를 조회할 때, 연관된 데이터를 어떻게 가져올지 결정
옵션설명특징
FetchType.EAGER엔티티 조회 시 즉시 조회초기 로딩이 느리고 불필요한 데이터까지 조회
FetchType.LAZY엔티티 조회 시 지연 조회초기 로딩이 빠르고 필요할 때만 참조 객체를 조회

💡 FetchType.LAZY는 성능 최적화에 유리하며, 실무에서 기본적으로 권장된다.
(필요한 시점에 참조엔티티.getXXX()를 통해 로딩)


🧠 [ JPA 커스텀 쿼리 ]


🧾 [ 쿼리 메소드 (Query Method) ]

  • SQL을 직접 작성하지 않고 메소드 이름으로 자동 쿼리 생성
  • 스프링 데이터 JPA에서 가장 많이 사용하는 방식

📘 규칙

형태설명
findBy필드명(String 필드값)SELECT * FROM 테이블명 WHERE 필드명 = ?
findBy이름And나이(String name, int age)다중 조건 검색
findBy이름Containing(String keyword)LIKE 검색 (부분 일치)

⚙️ 주의:

  • 반드시 카멜 표기법(CamelCase) 을 사용해야 한다.
  • 필드명은 Entity의 변수명 기준으로 작성한다.

📘 예시 코드

public interface MemberRepository extends JpaRepository<Member, Long> {
    List<Member> findByUsername(String username);
    List<Member> findByAgeGreaterThan(int age);
    List<Member> findByEmailContaining(String email);
}

🧩 [ 네이티브 쿼리 (Native Query) ]

  • SQL 문장을 직접 작성하여 실행하는 방식
  • 복잡한 쿼리나 JOIN, GROUP BY가 필요한 경우 사용

📘 예시 코드

@Query(value = "SELECT * FROM member WHERE email = :email", nativeQuery = true)
Member findByEmail(@Param("email") String email);
속성설명
value실행할 SQL 문장
nativeQuerytrue → 네이티브 SQL로 실행
:매개변수명파라미터 바인딩

💡 네이티브 쿼리는 SQL의 강력한 기능을 활용할 수 있지만, DB 종속성이 생긴다.


0개의 댓글