Home [JPA] JPA 기본 11
Post
Cancel

[JPA] JPA 기본 11

JPA 기본 11

경로 표현

경로 표현식

  • 점(.)을 찍어 객체 그래프를 탐색하는 것을 말한다.

  • 예시

    1
    2
    3
    4
    5
    
    select m.username // 상태 필드
    	from Member m 
    		join m.team t // 단일 값 연관 필드
    		join m.orders o // 컬렉션 값 연관 필드
    where t.name = 'teamA'
    

상태 필드

  • 단순히 값을 저장하기 위한 필드다.
  • 경로 탐색의 끝이다. 더 이상 탐색되지 않는다.

연관 필드

  • 단일 값 연관 필드
    • 대상이 엔티티다.
    • @ManyToOne, @OneToOne
    • 묵시적 내부 조인이 발생한다. 더 탐색된다.
  • 컬렉션 값 연관 필드
    • 대상이 컬렉션이다.
    • @OneToMany, @ManyToMany
    • 묵시적 내부 조인이 발생한다. 더 이상 탐색되지 않는다.
    • FROM 절에서 명시적 조인을 통해 별칭 획득 시, 별칭을 통한 탐색은 더 할 수 있다.

명시적, 묵시적 조인

명시적 조인

  • join 키워드를 직접 사용한다.

묵시적 조인

  • 경로 표현식에 의해 묵시적으로 SQL 조인이 발생한다. 내부 조인만 가능하다.

묵시적 조인 시 주의사항

  • 묵시적 조인은 항상 내부 조인을 사용하기에 경로 탐색 시 FROM 절에 영향을 줄 수 있음을 주의하자.
  • 컬렉션은 경로 탐색의 끝으로 명시적 조인을 통해 별칭을 얻어 경로 탐색을 지속할 수 있다.

조언

  • 묵시적 조인을 사용하지 말자!!
  • 명시적 조인을 사용하자.

페치 조인(fetch join)

  • SQL 조인 종류가 아니다.
  • JPQL에서 성능 최적화를 위해 제공하는 기능이다.
  • 연관된 엔티티나 컬렉션을 SQL 한번에 함께 조회하는 기능을 말한다.
  • join fetch 명령어를 통해 사용 가능하다.

엔티티 페치 조인

  • 회원을 조회하면서 연관된 팀도 함께 조회하고자 한다.

    1
    2
    
    // JPQL
    select m from Member m join fetch m.team
    

컬렉션 페치 조인

  • 예시

    1
    2
    
    // JPQL
    select t from Team t join fetch t.members where t.name='teamA'
    

페치 조인과 DISTINCT

  • SQL의 DISTINCT는 중복 결과를 제거하는 명령이다.

  • JPQL에서는 2가지 기능을 제공한다.

    1. SQL에 DISTINCT를 추가
    2. 애플리케이션에서 엔티티 중복을 제거
      • 같은 식별자를 가진 중복 엔티티를 제거해준다.
  • 예시

    1
    2
    
    // JPQL
    select distinct t from Team t join fetch t.members where t.name='teamA'
    

페치 조인과 일반 조인의 차이

  • 일반 조인 실행시 연관된 엔티티를 함께 조회하지 않는다.
  • JPQL은 결과를 반환할 때 연관관계를 고려하지 않는다.
  • 단지 select 절에 지정한 엔티티만을 조회한다.
  • 페치 조인을 사용할 때만 연관된 엔티티도 함께 조회한다.(즉시 로딩)
  • 페치 조인은 객체 그래프를 SQL 한번에 조회하는 개념이다.

페치 조인의 특징과 한계

  • 페치 조인 대상에는 별칭을 줄 수 없다.
    • 하이버네이트는 가능하다. 허나 사용을 피하도록 하자.
  • 둘 이상의 컬렉션은 페치 조인 할 수 없다.
  • 컬렉션 페치 조인 시 페이징 API 사용이 불가하다.
    • 일대일, 다대일 같은 단일 값 연관 필드들은 페치 조인해도 페이징 처리가 가능하다.
    • 하이버네이트는 경고 로그를 남기고 메모리에서 페이징하는 매우 위험한 로직을 가진다.
  • 연관된 엔티티들을 SQL 한 번으로 조회하여 성능을 최적화한다.
  • 엔티티에 직접 적용하는 글로벌 로딩 전략보다 우선한다.
    • 글로벌 로딩 전략 : @OneToMany(fetch=FetchType.LAZY)
  • 실무에서 글로벌 로딩 전략은 모두 지연 로딩을 따른다.
  • 최적화가 필요한 곳은 페치 조인이 적용된다.

페치 조인 정리

  • 모든 것을 페치 조인으로 해결하는 것은 불가능하다.
  • 페치 조인은 객체 그래프를 유지할 때 사용하면 효과적이다.
  • 여러 테이블을 조인해 엔티티가 가진 모양과 전혀 다른 결과를 내야 하는 경우, 페치 조인보다 일반 조인을 사용하고 필요한 데이터만 조회하여 DTO로 반환하는 것이 효과적이다.

다형성 쿼리

  • TYPE
  • TREAT

엔티티 직접 사용

기본 키 값

  • JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기본 키 값을 사용한다.

  • 엔티티를 파라미터로 전달하는 경우

    1
    2
    
    String jpql = "select m from Member m where m = :member";
    List result = em.createQuery(jpql).setParameter("member", member).getResultList();
    
  • 식별자를 직접 전달하는 경우

    1
    2
    
    String jpql = "select m from Member m where m.id = :memberId";
    List result = em.createQuery(jpql).setParameter("memberId", memberId).getResultList();
    
  • 실행된 SQL 문?

    1
    
    select m.* from Member m where m.id=?
    

외래 키 값

  • 엔티티를 파라미터로 전달하는 경우

    1
    2
    3
    4
    
    Team team = em.find(Team.class, 1L);
      
    String qlString = "select m from Member m where m.team = :team";
    List result = em.createQuery(qlString).setParameter("team", team).getResultList();
    
  • 식별자를 직접 전달하는 경우

    1
    2
    3
    4
    
    Team team = em.find(Team.class, 1L);
      
    String qlString = "select m from Member m where m.team.id = :teamId";
    List result = em.createQuery(qlString).setParameter("teamId", teamId).getResultList();
    
  • 실행된 SQL 문?

    1
    
    select m.* from Member m where m.team_id=?
    

Named 쿼리

정적 쿼리

  • 미리 정의해서 이름을 부여해두고 사용하는 JPQL이다.
  • 정적 쿼리
  • 어노테이션, XML에 정의한다.
  • 애플리케이션 로딩 시점에 초기화된다. 이후 재사용한다.
  • 애플리케이션 로딩 시점에 쿼리를 검증한다.

쿼리 환경에 따른 설정

  • XML이 항상 우선권을 가짐.
  • 애플리케이션 운영 환경에 따라 다른 XML 배포 가능.

벌크 연산

  • 쿼리 한 번으로 여러 엔티티의 로우를 변경하는 연산이다.
  • executeUpdate()의 결과는 영향받은 엔티티 수를 반환한다.
  • UPDATE, DELETE를 지원하고, 하이버네이트에서 INSERT를 지원한다.

주의할 점

  • 벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리한다. 꼬이는 것을 방지해야 한다.
    • 벌크 연산 먼저 실행하고, 수행이 끝나면 영속성 컨텍스트를 초기화하는 방식으로 해결 가능하다.
This post is licensed under younghwani by the author.

[JPA] JPA 기본 10

[Algorithm] BOJ 광고 1305

Comments powered by Disqus.