개발 낙서장

[TIL] 내일배움캠프 43일차 - JPQL 본문

Java/Sparta

[TIL] 내일배움캠프 43일차 - JPQL

권승준 2024. 2. 26. 21:27

오늘의 학습 키워드📚

쿼리 메소드

쿼리 메소드는 JpaRepository에서 메소드 네이밍을 통해 쿼리문을 작성할 수 있는 간편한 기능이다.

가령 User라는 테이블에서 username의 필드값을 통해 User를 찾고 싶다면

Optional<User> findByUsername(String username);

이렇게 간단한 메소드 네이밍을 통해 쿼리문을 만들 수 있다.

실제로 저 메소드를 실행하면 이런 쿼리가 날아가게 된다.

이런 식으로 어떤 식으로 작성해야 할지를 추천해 줘서 작성하기도 편하다.

하지만 형식에 맞지 않는 메소드 네이밍을 할 경우 에러가 발생하니 주의해야 한다.
(없는 필드로 찾으려 한다거나 오탈자가 있다거나 문법에 맞지 않다거나 등등...)

애초에 이런식으로 잘못 입력됐을 경우 IntelliJ에서 수정하라고 알려주기도 한다.

Could not create query for public abstract java.util.Optional com.sparta.mytodo.repository.UserRepository.findByUserKey(java.lang.Long); Reason: Failed to create query for method public abstract java.util.Optional com.sparta.mytodo.repository.UserRepository.findByUserKey(java.lang.Long);
No property 'userKey' found for type 'User'

이런 식으로 User 테이블에 userKey라는 프로퍼티는 없다고 에러가 발생한다.
그래서 간편하긴 한데 생각보다 자유롭지 않다.

User를 참조하는 TodoCard라는 테이블이 있다고 하자.
userId 값을 통해 TodoCard를 찾는 쿼리는 가능한데 그냥 쿼리 메소드에서는 불가능하다.

왜냐하면 JPA에 의해 TodoCard Entity에서 User가 userId로 참조하는게 아니라 User 객체로 참조하고 있기 때문이다.
실제 DB에는 userId가 참조키로 들어가 있지만 Jpa Entity에는 User 객체를 갖고 있다.
그래서 findByUserId 같은 쿼리 메소드를 사용하면 에러가 발생하고 findByUser로 찾아야 한다.

그럼 나만의 쿼리문을 작성해서 사용하고 싶은데 어떡하지?
이런 경우를 위해 @Query 라는 어노테이션에 쿼리문을 작성해 활용할 수 있다.
어노테이션을 메소드 위에 @Query("쿼리문") 이런 식으로 추가해 쿼리문을 직접 작성해줄 수 있다.

@Query("select t from TodoCard t where t.user.id = ?1 and t.isfinished = false")
List<TodoCard> findAllByUserAndIsFinishedIsFalse(Long userId);

이런 식으로 실제 SQL 쿼리문을 작성해 내가 원하는 파라미터, 필드 값을 통해 원하는 결과를 뽑아낼 수 있다.
?1은 받은 파라미터의 첫 번째 값을 의미한다.


오늘의 회고💬

팀 프로젝트를 진행했다. API 구현과 CRUD는 지금까지 많이 했던 거라 어렵지 않았는데 협업은 언제든 문제가 발생하는 것 같다. 처음으로 rebase를 사용했는데 conflict가 해결이 안 되면 rebase가 전혀 되지 않고 merge만 가능했다. 앞으로 사용하게 될 수도 있는 기능이어서 해결법을 확실히 익혀놔야겠다.

 

내일의 계획📜

구현한 기능을 토대로 테스트 코드를 전부 작성하고 예외 처리까지 한 다음에 시간이 남으면 추가 기능을 구현할 것 같다.

Comments