Query DSL

QueryDsl은 정적 타입을 이용해서 SQL과 같은 쿼리를 생성할 수 있도록 해주는 프레임워크

 

 

❓ 왜 사용할까?

 

Querydsl에서 java 코드를 사용하기 때문에 컴파일 시점에 타입 체크나 오타를 잡아주어 IDE의 도움을 받을 수 있다. 

Querydsl에서 파라미터를 바인딩 할 때 바로 넣을 수 있어 간편하고 가독성이 좋다.


🟥 build.gradle 설정

아래 사항을 모두 추가

//querydsl 추가
buildscript {
   dependencies {
      classpath("gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.10")
   }
}

//apply plugin: 'io.spring.dependency-management'
apply plugin: "com.ewerk.gradle.plugins.querydsl"

dependencies {
	//...//
	
    // QueryDSL 추가
   implementation 'com.querydsl:querydsl-jpa'
   implementation 'com.querydsl:querydsl-apt'
}

//querydsl 추가 시작 (버전 5.0.0 이후 추가된 세팅)
//def querydslDir = 'src/main/generated'
def querydslDir = "$buildDir/generated/querydsl"

querydsl {
   library = "com.querydsl:querydsl-apt"
   jpa = true
   querydslSourcesDir = querydslDir
}

sourceSets {
   main {
      java {
         srcDirs = ['src/main/java', querydslDir]
      }
   }
}

compileQuerydsl{
   options.annotationProcessorPath = configurations.querydsl
}

configurations {
   querydsl.extendsFrom compileClasspath
}
//querydsl 추가 끝

 

 


🟧 Query DSL 설정 파일

import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

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

    @Bean
    public JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(entityManager);
    }
}

 

 

 


🟨 Q클래스 생성

컴파일러를 돌리면 내가 프로젝트 내의 모든 Entity에 대한 Q클래스를 생성한다

 

 

 

 


🟩 구현

 

사용자 정의 인터페이스를 만든다.

public interface MemoRepositoryCustom {
    Long countLikeFromLikeMemo(Long Id);
}

 

구현체를 만드렁 Querydsl로 조회할 메서드를 구현한다. 

여기서 원하는 SQL을 날릴수 있도록 커스텀한다.

이때 메소드 안에 엔티티를 Q클래스를 생성해 그 안에서 데이터를 가져오는 것도 가능하다.

@Repository
public class MemoRepositoryImpl implements MemoRepositoryCustom {

    private final JPAQueryFactory jpaQueryFactory; // 의존성 주입

    public MemoRepositoryImpl(JPAQueryFactory jpaQueryFactory) {
        this.jpaQueryFactory = jpaQueryFactory;
    }

    @Override
    public Long countLikeFromLikeMemo(Long memoId){
        // Q클래스 사용
        QLikeMemo likeMemo = QLikeMemo.likeMemo;
        return jpaQueryFactory
                .select(likeMemo.count())
                .from(likeMemo)
                .where(
                        likeMemo.memo.id.eq(memoId)
                )
                .fetchOne();                              // 하나의 값만 반환
    }
}

 

이후 기존 JpaRepository에서 커스텀 레포지토리를 추가 상속한다. 

public interface MemoRepository extends JpaRepository<Memo, Long>, MemoRepositoryCustom {                                                           
    Long countLikeFromLikeMemo(Long Id);
}

 

그리고 기존 Repository에 선언했으므로 bean으로 등록되어 의존성 주입후 사용하면 된다.

 

 


🟦 Query DSL 기본 쿼리 메소드 (아주 간단하게)

  • select() : 조회 시작 메소드. 조회하려는 필드를 선택하고자 할때 매개값으로 조회할 사항을 선택할 수 있다.
  • from() : 조회하려는 엔티티 이름
  • selectFrom() : select하는 엔티티와 from의 엔티티가 일치할 경우, 그리고 그 엔티티의 모든 필드를 조회할 경우
  • where() : 데이터 조회 조건을 설정하는 부분
  • update() : 데이터 수정 시작 메소드
  • set() : 데이터 수정할 필드 이름을 첫번째 매개값으로, 넣을 값을 두번재 매개값으로 가진다.
  • delete() : 데이터 삭제 시작 메소드
  • fetchOne() : 단건 조회, 결과 조회가 없으면 Null
  • fetch() : 리스트 조회, 데이터 없으면 빈 리스트 반환
  • fetchFirst() : = limit(1).fetchOne() 가장 처음 조회되는 첫번째 한건을 조회
  • fetchCount() : count쿼리로 변환하여 조회되는 결과 수만 반환, long으로 반환
  • orderBy() : 정렬 방법
  • GroupBy() : 집합
  • join() : 기본적으로 Inner join에 leftJoin()은 left outer join, rightJoin()은 right outer join에 해당 된다.

+ Recent posts