티스토리 뷰

반응형

오늘은 JPARepository 내에서 사용하는 방법에 대한 가이드를 적어볼까 합니다. 보통 아래와 같이 SQL 을 작성하게 됩니다. 아래의 findById로 조회하는 경우 JPARepository 의 Override를 하게 되는것이기 때문에 우선권을 갖게 됩니다. 

@Query(value = "SQL")
Optional<Entity> findById(@Param("id") Long id);

 

근데 이와 같은 엔티티에 또 다른 엔티티가 Join이 되어 있는데, FetchType=LAZY인 경우 데이터를 가져오는 경우 쿼리가 2번 호출됩니다.

AClass.java

@Entity
public class AClass {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;
    
    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private BClass bclass;
}

 

AClassRepository.java

@Query(value = "SELECT a FROM AClass a WHERE a.id = :id")
Optional<AClass> findById(@Param("id") Long id);

 

SELECT
    *
FROM 
    a_class a
WHERE 
	a.id = ?
    
=====================================    
select
   b.column1 as column1_17_0,
   b.column2 as column2_17_1
from
   b_class 
where
   id = ?

⚠️ 엔티티 내용에 따라 JPA 에서 자동으로 만들어주는 컬럼은 차이가 있을 수 있습니다.

 

그래서 쿼리가 2번 나가게 되는 N+1 의 문제가 발생하게 되기 때문에 Repository 의 쿼리 내에서 다음과 같은 방법으로 조인을 걸게 되면 작동됩니다. 

변경된 AClassRepository.java

@Query(value = "SELECT a, b FROM AClass a " + 
       "LEFT JOIN BClass b ON a.bclass_id = b.id " + 
       "WHERE a.id = :id")
Optional<AClass> findById(@Param("id") Long id)

 

그리고 출력

select 
    a.id,
    a.b_class_id,
    b.col1,
    b.col2
from
   a_class a
left outer join
    b_class b
        ON ( 
           b.id = a.b_class_id
        )
where 
    a.id = ?

⚠️ 엔티티 내용에 따라 JPA 에서 자동으로 만들어주는 컬럼은 차이가 있을 수 있습니다. 

 

도움이 되셨길 바랍니다 :)

반응형
댓글
공지사항