왜 QueryDSL 인가?
JPA QueryDSL을 사용하면 문자열 기반 쿼리 대신에 Java 코드로 쿼리를 작성할 수 있으므로, 컴파일 시점에서 오류를 검출할 수 있고 IDE에서 코드 자동완성 등의 기능을 사용할 수 있다는 장점이 있다.
JPA QueryDSL의 세팅 방법은 다음과 같다.
- 의존성 추가: JPA QueryDSL 라이브러리를 사용하기 위해서는 라이브러리의 의존성을 추가해야 한다. 예를 들어, Maven을 사용하는 경우에는 pom.xml 파일에 다음과 같이 의존성을 추가할 수 있다.
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>{version}</version>
</dependency>
- Q 클래스 생성: JPA QueryDSL을 사용하려면 Q 클래스를 생성해야 한다. Q 클래스는 엔티티 클래스의 필드를 정의한 클래스로, 쿼리 작성 시에 사용된다. Q 클래스는 JPA QueryDSL의 코드 생성 플러그인을 사용하여 자동으로 생성할 수 있다.
- JPAQueryFactory 생성: JPAQueryFactory는 쿼리를 실행할 때 사용하는 객체로, EntityManager를 인자로 받아 생성된다. JPAQueryFactory는 스프링 프레임워크에서는 @Bean 어노테이션을 사용하여 빈으로 등록할 수 있다.
JPA QueryDSL의 사용법은 다음과 같다.
- JPAQueryFactory 객체 생성: EntityManager를 인자로 받아 JPAQueryFactory 객체를 생성한다.
@Autowired
private EntityManager entityManager;
private JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
- 쿼리 작성: Q 클래스를 사용하여 타입 안전한 쿼리를 작성한다.
예를 들어, 다음은 엔티티 클래스인 User와 Q 클래스인 QUser를 사용하여 이름이 "John"인 유저를 조회하는 쿼리이다.
QUser qUser = QUser.user;
List<User> userList = queryFactory
.selectFrom(qUser)
.where(qUser.name.eq("John"))
.fetch();
아래 코드는 JPA의 다중 조회 결과를 활용한 예시입니다. JPA에서 다중 조회는 서브 쿼리를 사용하거나 여러 개의 쿼리를 작성하여 수행할 수 있습니다. 하지만 QueryDSL을 사용하면 더 간편하고 직관적인 코드를 작성할 수 있습니다.
QUser user = QUser.user;
QOrder order = QOrder.order;
QOrderItem orderItem = QOrderItem.orderItem;
List<User> users = queryFactory
.selectFrom(user)
.where(user.name.like("%" + name + "%"))
.fetch();
List<Order> orders = queryFactory
.selectFrom(order)
.where(order.user.in(users))
.fetch();
List<OrderItem> orderItems = queryFactory
.selectFrom(orderItem)
.where(orderItem.order.in(orders))
.fetch();
Map<Order, List<OrderItem>> orderItemMap = orderItems.stream()
.collect(Collectors.groupingBy(OrderItem::getOrder));
List<OrderDto> result = orders.stream()
.map(order -> new OrderDto(order, orderItemMap.get(order)))
.collect(Collectors.toList());
위 코드에서는 먼저 QUser
, QOrder
, QOrderItem
클래스를 사용하여 QueryDSL에서 사용할 쿼리 객체를 정의합니다. 그 후 queryFactory
객체를 사용하여 각각의 쿼리를 작성합니다. selectFrom()
메서드로 조회할 엔티티를 지정하고, where()
메서드로 검색 조건을 설정합니다. 마지막으로 fetch()
메서드를 호출하여 쿼리를 수행하고 결과를 반환합니다.
위 코드에서는 다중 조회 결과를 처리하기 위해 Java 8의 Stream API를 사용합니다. 먼저 orders
와 orderItems
를 조회한 후, orderItemMap
에 각 Order
객체와 그에 대한 OrderItem
객체들을 매핑합니다. 그리고 orders
와 orderItemMap
을 사용하여 OrderDto
객체를 생성하고 이를 result
리스트에 추가합니다.
이처럼 QueryDSL을 사용하면 JPA에서 지원하는 복잡한 쿼리도 간편하게 작성할 수 있으며, 코드의 가독성과 유지보수성을 높일 수 있습니다.
JPA QueryDSL의 장단점은?
장점:
- 타입 안전한 쿼리 작성이 가능하여 컴파일 시점에서 오류를 검출할 수 있다.
- 코드 자동완성 등의 기능을 사용할 수 있어 개발 생산성이 향상된다.
- 문자열 기반 쿼리 대신에 Java 코드로 쿼리를 작성하므로, 쿼리의 가독성이 향상된다.
단점:
추가적인코드 생성 플러그인을 사용하여 Q 클래스를 생성해야 하므로, 프로젝트 설정이 번거로울 수 있다.
- 복잡한 쿼리를 작성하는 경우에는 코드의 복잡도가 증가할 수 있다.
- JPA QueryDSL을 학습하고 익히는데 시간이 필요할 수 있다.
총평하자면, JPA QueryDSL은 JPA를 사용하는 애플리케이션에서 쿼리 작성을 타입 안전하게 할 수 있도록 도와주는 라이브러리이다. 사용하면서 발생할 수 있는 설정의 어려움과 복잡도, 그리고 학습에 대한 시간 투자를 고려하여 사용 여부를 결정해야 한다.
내저장소 바로가기 luxury515
'Back-end > JPA' 카테고리의 다른 글
JPA에서 Specification 사용해보기 (0) | 2023.04.13 |
---|---|
JPA 에서 복합키 를 사용하는 이유 ,구현 방법. (0) | 2023.04.11 |
JoinColumn vs MappedBy 에 관하여 (0) | 2023.04.11 |
JPA의 N+1 문제가 발생하는 이유 , 그리고 그 해결 방안에 대한 연구 (0) | 2023.04.11 |
JPA에서 벌크 insert를 수행하는 몇 가지 방법 (0) | 2023.04.11 |