⏰ 2024. 07. 05 금
✔ 스프링 이론 강의를 듣고 정리하면서 작성했습니다.
QueryDSL
정적 타입을 이용하여 SQL과 같은 쿼리를 하드코딩하는 것이 아닌 코드 형태로 생성할 수 있도록 해주는 오픈소스 빌더 API이다.
Entity의 매핑 정보를 활용하여 Query에 적합하도록 Query 전용 클래스(Q-Class)로 재구성해주는 기술이다.
JPAQueryFactory를 통한 Q-Class를 활용할 수 있는 기능을 제공한다.
⚡ Q-Class
- JPAAnnotationProcessor가 컴파일 시점에
@Entity
와@Embeddedable
과 같은 애너테이션이 설정된 클래스를 Query 객체 형태로 생성한 클래스이다.- 해당 객체에 쿼리문을 메서드 형태로 호출하여 SQL문을 짜듯이 함수형태의 코드로 쿼리문 작성이 가능하다.
⚡ JPAQueryFactory
- 재구성한 Q-Class를 통해 문자열이 아닌 객체 또는 함수로 Query를 작성하고 실행하게 해주는 기술
build.gradle
의존성 추가(SpringBoot 3.0.x 버전 이상) // QueryDSL 적용을 위한 의존성
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
entityManager
를 주입해서 수동으로 빈(@Bean)
으로 등록해야한다. @Configuration
public class JPAConfiguration {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
@Query
애너테이션을 통해 쿼리문을 문자열
형태로 작성하는 방법이다. @Query("select e from entity e where e.id = ?1 and e.name = ?2")
Entity findEntity(Long id, String name);
JPQL의 문제점은 쿼리문을 문자열 형태로 작성하기 때문에 오타나 잘못된 필드명을 입력할 시, 의도적으로 확인하지 않으면 컴파일 과정에서 식별되지 않기 때문에 런타임 에러가 발생한다.
JPQL과 같이 쿼리문을 문자열로 작성하여 컴파일 과정에서 식별할 수 없는 문제를 해결하기 위해 나온 프레임워크가 QueryDSL
이다.
// JPAConfiguration 생성!
@Repository
@RequiredArgsConstructor
public class RepositoryQueryImpl implements RepositoryQuery {
private final JPAQueryFactory jpaQueryFactory;
public List<Entity> getEntityByIdAndName(Long id, String name){
QEntity entity = QEntity.entity;
List<Person> entityList = jpaQueryFactory
.selectFrom(entity)
.where(entity.id.eq(id)
.and(entity.name.eq(name))
.fetch();
return entityList;
}
}
Query문이 문자열이 아닌 함수
형태로 조합되어 최종 결과를 반환한다.
JPA Entity와 연동되어 조회 시 영속성 컨텍스트를 참조한다.
@Entity
로 등록된 모든 Class에 대해 Q-Class
를 만들고, 그 안에 멤버 변수로 정의된 컬럼들에 대한 연산들을 메서드 형태로 컴파일 시점에 생성한다.
컴파일 시점에 만들기 때문에, 컴파일하는 과정에서 에러가 식별됨으로 런타임에 발생할 에러를 줄일 수 있다.