[spring] JPQL과 QueryDSL 차이점

kongta2·2024년 1월 24일
0
  1. JPQL
  • JPA Repository에 Custom function에 @Query 어노테이션을 통해 쿼리문을 작성하는 방법
public interface PersonRepository extends JpaRepository<Person, Long>{

	/*	변수 바인딩 시, ?시퀀스 사용하는 경우 */
   @Query("select p from Person p where p.firstName = ?1 and p.lastName = ?2")
   Person findPerson(String firstName, String lastName);

   /*	변수 바인딩 시, :이름 사용하는 경우 */
   @Query("select p from Person p where p.firstName = :firstName and p.lastName = :lastName")
   Person findPerson2(@Param("firstName") String firstName, @Param("lastName") String lastName);

}
  • @Query 영역에 들어가는 조회문이 문자열인 점에 주목하자.
    • 만약, 예제에서 보이는 것 처럼 Person 엔티티의 스펙이 변경 되는 경우에는 어떻게 될까?
      • 예를 들어, “firstName”이 “fName”으로 변경되었다고 가정하자. 또한, 해당 API의 호출 건수는 매우 적어 6개월에 한 번씩 일어난다고 가정하자.
      • 변경된 후, application를 빌드하여 실제 운영 중인 서버에 올렸다.
      • 6개월 후, 어떤 사용자가 해당 API를 호출했고.. 에러와 함께 해당 기능이 실행되지 않는다.
        • → 즉, 개발자는 에러 사항을 6개월 후에 확인할 수 있는 것이다.
      • CRUD에 관련된 연산이 문자열로 이루어진 경우, Run time시에 해당 에러를 확인할 수 있다.
      • Compile 단계에서 Type-Check가 불가능하여, 장애 Risk가 상승한다.
  1. QueryDSL
  • JPQL과 같이, 쿼리문을 문자열로 작성하여, Compile 시에 Type-Check가 되지 않았던 문제를 해결하기 위해 나온 프레임워크
@PersistenceContext
EntityManager em;

public List<Person> selectPersonByNm(String firstNm, String lastNm){
	JPAQueryFactory jqf = new JPAQueryFactory(em);
	QPerson person = QPerson.person;

	List<Person> personList = jpf
								.selectFrom(person)
								.where(person.firstName.eq(firstNm)
									.and(person.lastName.eq(lastNm))
								.fetch();

	return personList;
}
  • 쿼리가 문자열 형태가 아닌, 함수 형태로 조합되어 최종 결과를 반환한다.
  • JPA Entity와 연동되어, 조회 시 영속성 컨텍스트를 참조한다.
  • 앞서 JPQL 예제에서 봤던 것 처럼 Person 엔티티의 스펙이 변경 되는 경우에는 어떻게 될까?
    • QueryDSL를 이용하는 경우, @Entity로 등록된 모든 클래스에 대한 Q-객체를 만들고, 그 안에 멤버 변수로 정의된 컬럼들에 대한 연산들을 메서드 형태로 Compile-time에 생성한다.
    • 즉, Compile-time에 에러가 식별되기 때문에 장애 Risk를 크게 줄일 수 있다.
profile
2025.04.01~

0개의 댓글