본문 바로가기
JPA/Querydsl

Querydsl 01 - 프로젝트 만들고 설정하기

by 킹차니 2022. 1. 15.

build.gradle :

 

먼저 아래와 같은 의존성을 추가하여 스프링 부트 프로젝트를 만든다.

그리고 아래와 같은 플러그인을 추가해야 한다.

id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
buildscript {
   ext {
      queryDslVersion = "5.0.0"
   }
}

plugins {
   id 'org.springframework.boot' version '2.6.2'
   id 'io.spring.dependency-management' version '1.0.11.RELEASE'
   //querydsl 추가
   id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
   id 'java'
}

group = 'study'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
   compileOnly {
      extendsFrom annotationProcessor
   }
}

repositories {
   mavenCentral()
}

dependencies {
   implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
   implementation 'org.springframework.boot:spring-boot-starter-web'
   //querydsl 추가
   implementation "com.querydsl:querydsl-jpa:${queryDslVersion}"
   implementation "com.querydsl:querydsl-apt:${queryDslVersion}"
   // -- 여기까지
   compileOnly 'org.projectlombok:lombok'
   runtimeOnly 'com.h2database:h2'
   annotationProcessor 'org.projectlombok:lombok'
   testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
   useJUnitPlatform()
}

//querydsl 추가 시작
def querydslDir = "$buildDir/generated/querydsl"

querydsl {
   jpa = true
   querydslSourcesDir = querydslDir
}
sourceSets {
   main.java.srcDir querydslDir
}
compileQuerydsl{
   options.annotationProcessorPath = configurations.querydsl
}
configurations {
   compileOnly {
      extendsFrom annotationProcessor
   }
   querydsl.extendsFrom compileClasspath
}
//querydsl 추가 끝

 

이제 설정 확인을 위한 엔티티를 만들어보자.

@Getter @Setter
@Entity
public class Hello{

    @Id @GeneratedValue
    private Long id;
}

 

이제 이를 compileQuerydsl을 해줘야 한다.

compileQuerydsl을 하고 나면 build/generated/querydsl/study/querydsl/entity에 QHello라는 클래스가 생긴 것을 볼 수 있다.

package study.querydsl.entity;

import static com.querydsl.core.types.PathMetadataFactory.*;

import com.querydsl.core.types.dsl.*;

import com.querydsl.core.types.PathMetadata;
import javax.annotation.processing.Generated;
import com.querydsl.core.types.Path;


/**
 * QHello is a Querydsl query type for Hello
 */
@Generated("com.querydsl.codegen.DefaultEntitySerializer")
public class QHello extends EntityPathBase<Hello> {

    private static final long serialVersionUID = 1910216155L;

    public static final QHello hello = new QHello("hello");

    public final NumberPath<Long> id = createNumber("id", Long.class);

    public QHello(String variable) {
        super(Hello.class, forVariable(variable));
    }

    public QHello(Path<? extends Hello> path) {
        super(path.getType(), path.getMetadata());
    }

    public QHello(PathMetadata metadata) {
        super(Hello.class, metadata);
    }

}

build.gradle에서 "$buildDir/generated/querydsl" 로 경로를 설정했기에 해당 경로 아래에 QHello클래스가 생성된 것이다.

 

이제 Querydsl이 잘 실행되는지 아래와 같은 간단한 테스트를 해보자.

@Transactional
@SpringBootTest
class QuerydslApplicationTests {

   @Autowired EntityManager em;

   @Test
   void contextLoads() {
      Hello hello = new Hello();
      em.persist(hello);

      JPAQueryFactory query = new JPAQueryFactory(em);
      QHello qHello =QHello.hello;
      Hello result = query
            .selectFrom(qHello)
            .fetchOne();

      assertThat(result).isEqualTo(hello);
      assertThat(result.getId()).isEqualTo(hello.getId());
   }
   // -> 테스트 성공
}

 

 


이제 학습을 위한 예제 도메인 모델을 만들어 보자.

 

Member 엔티티

@ToString(of={"id", "username", "age"})
@NoArgsConstructor(access= AccessLevel.PROTECTED)
@Getter @Setter
@Entity
public class Member {
    @Id @GeneratedValue
    @Column(name="member_id")
    private Long id;
    private String username;
    private int age;

    @JoinColumn(name="team_id")
    @ManyToOne(fetch = LAZY)
    private Team team;

    public void changeTeam(Team team) {
        this.team = team;
        team.getMembers().add(this);
    }

    public Member(String username) {
        this.username = username;
    }

    public Member(String username, int age, Team team) {
        this.username = username;
        this.age = age;
        if(team!=null) changeTeam(team);
        this.team = team;
    }

    public Member(String username, int age) {
        this.username = username;
        this.age = age;
    }

}

 

Team엔티티

@ToString(of={"id", "name"})
@NoArgsConstructor(access= AccessLevel.PROTECTED)
@Getter @Setter
@Entity
public class Team {
    @Id @GeneratedValue
    @Column(name="member_id")
    private Long id;
    private String name;

    @OneToMany(mappedBy = "team", cascade=CascadeType.ALL)
    private List<Member> members = new ArrayList<>();

    public Team(String name) {
        this.name = name;
    }
}

 

 

 

 

 

김영한님의 인프런 강의와 PDF를 바탕으로 정리하였습니다.