제대로 배운 것은 아니고 잠깐 프로젝트에서 사용을 해본 것을 기록해봤다.
먼저 gradle 의존성을 추가해준다.
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'
annotationProcessor 'jakarta.annotation:jakarta.annotation-api'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api'
그 다음에 ./gradlew clean compileJava 를 입력하면 ./build/generated/sources/annotationProcessor/java/main/ 위치에 Q class가 생기게 된다.
그 다음에 QueryDSL Config를 작성해줘야 한다. JPAQueryFactory를 주입해줄 수 있도록 하는 것이다.
그럼 QueryDSL 을 사용할 준비는 끝난 것이다.
그리고 코드를 작성하면 다음과 같아진다.
UserRepository를 interface로 만들어서 기능에 필요한 애들을 메소드 시그니처로 작성해놓고 구현체에 JPA를 쓸 건지 QueryDSL을 쓸 건지 선택해서 Override하는 형태이다.
@Component
@RequiredArgsConstructor
public class UserRepositoryAdapter implements UserRepository {
private final JpaUserRepository jpaUserRepository;
private final JPAQueryFactory queryFactory;
@Override
public User save(User user) {
return jpaUserRepository.save(user);
}
@Override
public User findById(Long id) {
return jpaUserRepository.findById(id).orElseThrow(
() -> new BusinessException(ErrorCode.USER_NOT_FOUND)
);
}
@Override
public User findByName(String name) {
return jpaUserRepository.findByName(name).orElseThrow(
() -> new BusinessException(ErrorCode.USER_NOT_FOUND)
);
}
@Override
public boolean existsByName(String name) {
return jpaUserRepository.existsByName(name);
}
@Override
public Integer findMaxDriverOrderByHubId(UUID hubId) {
Integer result = queryFactory
.select(driver.order.max().coalesce(0))
.from(user)
.join(user.driver, driver)
.where(driver.hubId.eq(hubId))
.fetchOne();
return result != null ? result : 0;
}
@Override
public Integer findMaxHubDriverOrder() {
Integer result = queryFactory
.select(driver.order.max().coalesce(0))
.from(user)
.join(user.driver, driver)
.where(driver.hubId.isNull())
.fetchOne();
return result != null ? result : 0;
}
public void delete(User user, Long requesterId) {
user.markDeleted(requesterId);
}
}
원래 JPA 코드
// index 생성 예정 : hub_id, order
@Query("""
select coalesce(max(d.order), 0)
from User u
join u.driver d
where d.hubId = :hubId
""")
Integer findMaxDriverOrderByHubId(@Param("hubId") UUID hubId);
@Query("""
select coalesce(max(d.order), 0)
from User u
join u.driver d
where d.hubId is null
""")
Integer findMaxHubDriverOrder();
이후 코드
@Override
public Integer findMaxDriverOrderByHubId(UUID hubId) {
Integer result = queryFactory
.select(driver.order.max().coalesce(0))
.from(user)
.join(user.driver, driver)
.where(driver.hubId.eq(hubId))
.fetchOne();
return result != null ? result : 0;
}
@Override
public Integer findMaxHubDriverOrder() {
Integer result = queryFactory
.select(driver.order.max().coalesce(0))
.from(user)
.join(user.driver, driver)
.where(driver.hubId.isNull())
.fetchOne();
return result != null ? result : 0;
}
뭔가 이해하기 쉽고 간결한 코드 작성이 된다고 생각한다.