- 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가 상승한다.
- 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를 크게 줄일 수 있다.