BACKEND/SPRING

Spring Data JPA 활용 - @Query 어노테이션과 QueryDSL

우진하다 2023. 8. 13. 22:17

Spring Data JPA는 쿼리 메서드의 이름을 기반으로 자동으로 쿼리를 생성할 수 있지만, 
때로는 개발자가 정확한 쿼리를 작성해야 할 필요가 있습니다. 
이때 사용하는 것이 @Query 어노테이션입니다.
QueryDSL은 타입-세이프한 방식으로 쿼리를 작성하는 프레임워크로, 복잡한 쿼리의 작성과 재사용을 도와줍니다.

@Query 어노테이션

Spring Data JPA는 @Query 어노테이션을 통해 JPQL 또는 SQL을 직접 사용하여 데이터베이스 쿼리를 지정할 수 있게 합니다. 
이는 기본 제공되는 메서드 이름 기반 쿼리로 해결하기 어려운 복잡한 쿼리 요구 사항을 처리하는 데 유용합니다.

JPQL 지원: Java Persistence Query Language를 사용하여 객체 지향 쿼리를 작성할 수 있습니다.
Native Query 지원: 데이터베이스 특정 쿼리를 직접 작성할 수 있습니다.

public interface UserRepository extends JpaRepository<User, Long> {
    
    @Query("SELECT u FROM User u WHERE u.email = ?1")
    User findByEmail(String email);
    
    @Query(value = "SELECT * FROM users WHERE first_name = ?1", nativeQuery = true)
    User findByFirstNameNative(String firstName);
}

 

 QueryDSL

QueryDSL은 복잡한 쿼리 작업과 동적 쿼리 생성을 위한 프레임워크입니다. 
JPQL의 문자열 기반 쿼리와는 달리, QueryDSL은 타입-세이프한 방법을 제공하여 컴파일 시점에 쿼리 오류를 확인할 수 있습니다.

타입-세이프 쿼리: 컴파일 시점에 쿼리의 오타나 오류를 잡을 수 있습니다.
동적 쿼리 작성: 조건문을 사용하여 동적으로 쿼리를 생성하고 실행할 수 있습니다.

public class UserRepositoryCustomImpl implements UserRepositoryCustom {
    private final JPAQueryFactory queryFactory;

    public UserRepositoryCustomImpl(EntityManager em) {
        this.queryFactory = new JPAQueryFactory(em);
    }

    @Override
    public List<User> findCustomMethod(String email) {
        QUser user = QUser.user;
        return queryFactory
                .selectFrom(user)
                .where(user.email.eq(email))
                .fetch();
    }
}