[Spring] QueryDSL, JPQL에서 변경하기.

Kim yoon beom·2025년 5월 9일
0

QueryDSL에 대해서는 추후에 더 공부가 필요해 보인다.


  • 해당 코드
public TodoResponse getTodo(long todoId) {
        Todo todo = todoRepository.findByIdWithUser(todoId)
                .orElseThrow(() -> new InvalidRequestException("Todo not found"));

        User user = todo.getUser();

        return new TodoResponse(
                todo.getId(),
                todo.getTitle(),
                todo.getContents(),
                todo.getWeather(),
                new UserResponse(user.getId(), user.getEmail(), user.getNickname()),
                todo.getCreatedAt(),
                todo.getModifiedAt()
        );
    }
  • build.gradle에 해당(QueryDSL) 의존성 주입.
// QueryDSL(SpringBoot3.0 부터는 jakarta 사용해야함)
    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"

1. 커스텀 리포지토리 인터페이스 생성.

2. 커스텀 리포지토리 구현체 생성.


Q클래스가 생성이 되지 않는다.


분명 gradle이 설치되어 있는데, 터미널에 gradle wrapper를 해도 오류가 발생한다.

찾아보니까 gradle-wrapper.properties가 없으면 안된다고 한다.

반드시 gradle/wrapper/gradle-wrapper.properties, gradle-wrapper.jar 파일이 필요


이미 wrapper가 있는 다른 프로젝트의 gradle/wrapper 폴더 전체를 현재 프로젝트의 같은 위치에 복사해도 된다고 하길래

지지난주 팀 과제 프로젝트에서 gradle-wrapper.properties파일을 가져왔다.

이러고 ./gradlew clean build 를 터미널에 입력하니까 Q클래스가 import가 된다.


🤔 해결이 되긴했는데 잘되다가 갑자기 wrapper.properties가 없어진 이유는?

1. 프로젝트 클린/리빌드, 또는 Gradle/IntelliJ 설정 문제

2. git clone/checkout 시 누락

3. 로컬 환경의 캐시/설정 오류

클론한 깃 프로젝트의 .gitignore 파일을 보니까 wrapper.jar에 관한 내용은 있는데 wrapper.properties가 없다.

이게 문제인가?

3. 리포지토리에 상속을 추가.


최종 코드.

package org.example.expert.domain.todo.repository;

import org.example.expert.domain.todo.entity.Todo;

import java.util.Optional;

public interface TodoRepositoryQueryDsl {
    Optional<Todo> findByIdWithUser(Long todoId);
}
package org.example.expert.config;

import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QueryDslConfig {
    @PersistenceContext
    private EntityManager entityManager;

    @Bean
    public JPAQueryFactory jpaQueryFactory(){
        return new JPAQueryFactory(entityManager);
    }
}
package org.example.expert.domain.todo.repository;

import org.example.expert.domain.todo.entity.Todo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.time.LocalDateTime;
import java.util.Optional;

public interface TodoRepository extends JpaRepository<Todo, Long>, TodoRepositoryQueryDsl {

    @Query("SELECT t FROM Todo t "
            + "LEFT JOIN FETCH t.user u "
            + "WHERE (:weather is null OR t.weather LIKE :weather) "
            + "AND (:start is null OR t.modifiedAt >= :start) "
            + "AND (:end is null OR t.modifiedAt <= :end) "
            + "ORDER BY t.modifiedAt DESC")
    Page<Todo> findAllByFilters(
            Pageable pageable,
            @Param("weather") String weather,
            @Param("start") LocalDateTime start,
            @Param("end") LocalDateTime end
    );

    @Query("SELECT t FROM Todo t " +
            "LEFT JOIN t.user " +
            "WHERE t.id = :todoId")
    Optional<Todo> findByIdWithUser(@Param("todoId") Long todoId);
}
  • fetchJoin()을 사용해서 N+1 문제를 해결.
profile
나는.원한다.개발자

0개의 댓글