개요
Spring Data JPA를 사용하면 간단한 쿼리는 쿼리 메서드로 해결할 수 있다.
관계를 맺고 있는 Entity의 ID(=조인 컬럼, FK)를 알고 있을 때, 바로 해당 ID로 Entity를 조회하는 방식으로 쿼리 메서드를 작성하고 싶을 수 있다. 즉, 성능향상을 위해 두 번째 방법을 선택한다는 것이다.
(1) Entity A ID로써 Entity A 조회 -> Entity A로 Entity B 조회
(2) Entity A ID로써 Entity B 조회
그러나 조인 컬럼을 이용하여 쿼리 메서드를 만들 때는 의도치 않은 OUTER JOIN이 발생할 수 있으므로 주의해야 한다.
예제
User와 다대일 관계를 맺고 있는, 즉 user_no를 FK로 갖고 있는 Admin이 있다.
Admin
public class Admin {
// ...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_no")
private User user;
}
User
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_no")
private Long no;
// ...
}
AdminRepository
public interface AdminRepository extends JpaRepository<Admin, Long> {
Optional<Admin> findByUser_No(Long userNo);
@Query("SELECT a from Admin a WHERE a.user.no = :userNo")
Optional<Admin> findByUserNo(@Param("userNo") Long userNo);
}
- findByUser_No는 조인컬럼을 이용한 쿼리 메서드이다
- findByUserNo는 @Query 어노테이션을 이용해 JPQL형태로 작성된 메서드이다
AdminRepositoryTest
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class AdminRepositoryTest {
@Autowired
private AdminRepository adminRepository;
@Test
@DisplayName("쿼리 출력")
void findByUserNo() {
adminRepository.findByUser_No(1L);
adminRepository.findByUserNo(1L);
}
}
결과
// findByUser_No
Hibernate:
select
adminentit0_.admin_no as admin_no1_0_,
adminentit0_.ins_datetime as ins_date2_0_,
adminentit0_.upd_datetime as upd_date3_0_,
adminentit0_.chat_room_no as chat_roo4_0_,
adminentit0_.user_no as user_no6_0_
from
chat_room adminentit0_
left outer join
user userentity1_
on adminentit0_.user_no=userentity1_.user_no
where
userentity1_.user_no=?
// findByUserNO
Hibernate:
select
adminentit0_.admin_no as admin_no1_0_,
adminentit0_.ins_datetime as ins_date2_0_,
adminentit0_.upd_datetime as upd_date3_0_,
adminentit0_.chat_room_no as chat_roo4_0_,
adminentit0_.user_no as user_no6_0_
from
chat_room adminentit0_
where
adminentit0_.user_no=?
- 조인컬럼을 이용한 쿼리 메서드에서 추가적인 left outer join이 발생한 것을 확인할 수 있었다
결론
- Spring Data JPA에서 조인컬럼(FK)을 이용해 쿼리 메서드를 작성할 때는 추가적인 JOIN이 발생할 수 있으므로 주의한다
- 쿼리 메서드 이용 시엔 Entity를 통해 조회하거나 네이티브 쿼리, JPQL 등 별도의 방법을 이용한다
'JPA' 카테고리의 다른 글
[JPA] 실무에서 만난 N+1 문제 해결하기 (feat. LazyInitializationException) (1) | 2023.10.25 |
---|---|
[JPA] StoredProcedureQuery execute와 executeUpdate 차이 및 사용법 (0) | 2022.11.23 |
[JPA] 스프링 데이터 JPA의 JpaRepository 구현체 분석 (0) | 2022.07.26 |