querydsl 설정하기
querydsl
Spring Data JPA에서 제공되는 @Query만으로는 다양한 조회 문제를 해결하기 어렵습니다. querydsl을 사용하면 java code에서 마치 직접 쿼리를 작성하듯 가능합니다.
querydsl을 사용하기 하려면 어떠한 것들을 준비해야하는지 간단히 소개하려고합니다.
테스트할 Entity 준비
querydsl 사용에 앞서 간단한 Entity하나를 준비합니다. Item(상품) Entity이며 테스트 용도라서 이름, 가격만을 갖도록 단순히 구성했습니다.
@Entity
@Getter
public class Item {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "item_id")
private Long id;
@Column
private String name;
@Column
private String price;
}
dependency 추가
querydsl을 사용하기 위해서는 spring-boot-starter-data-jpa 외에 별도로 dependency가 필요합니다.
- querydsl-jpa : querydsl의 core library로, chaining 방식의 쿼리 작성을 가능하게 해줍니다.
- querydsl-apt : Entity class와 대응하는 querydsl에서 사용될 Q로 시작하는 클래스파일을 생성해주는 library라고합니다. 뒤에 설명하겠지만 compile단계에서 QItem class 파일이 자동 생성됩니다.
pom.xml
...
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>4.3.1</version>
</dependency>
...
build 설정
compile단계에서 자동으로 generate된 Q로 시작하는 QClass파일이 저장될 경로 설정이 필요하고, 아래와 같이 target디렉토리 하위에 적당한 위치로 설정해줍니다.
<build>
<plugins>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
QClass
querydsl-apt 에 의해 Item Entity class를 기반으로 “알아서” 아래와 같은 클래스를 만들어줍니다. querydsl로 쿼리를 작성할 때 Qclass가 이용됩니다. 이와 비슷한 JOOQ라는 library는 실제 DB접속을 통해 QClass와 같은 클래스를 별도 script로 생성해야하는 번거로움이 있는 반면, jpa querydsl은 Entity class기반으로 compile단계에서 자동 생성되고 클래스 이름기반의 convention으로 상대적으로 사용하기 더 편하다고합니다.
/**
* QItem is a Querydsl query type for Item
*/
@Generated("com.querydsl.codegen.EntitySerializer")
public class QItem extends EntityPathBase<Item> {
private static final long serialVersionUID = 1743385104L;
public static final QItem item = new QItem("item");
public final NumberPath<Long> id = createNumber("id", Long.class);
public final StringPath name = createString("name");
public final StringPath price = createString("price");
public QItem(String variable) {
super(Item.class, forVariable(variable));
}
public QItem(Path<? extends Item> path) {
super(path.getType(), path.getMetadata());
}
public QItem(PathMetadata metadata) {
super(Item.class, metadata);
}
}
테스트
그럼 자동으로 생성된 Qclass인 QItem 클래스가 어떻게 사용되는지 아래 예제에서 확인해보겠습니다.
@SpringBootTest
@Transactional
class JavaPlaygroundApplicationTests {
@Test
void 아주간단한_querydsl_시험해보기() {
Item item = new Item();
em.persist(item);
JPAQueryFactory query = new JPAQueryFactory(em);
QItem qItem = QItem.item;
Item result = query
.selectFrom(qItem)
.where(qItem.name.eq("에어팟프로"))
.fetchOne();
Assertions.assertThat(result).isEqualTo(item);
Assertions.assertThat(result.getId()).isEqualTo(item.getId());
}
}
결론
- querydsl을 사용하려면 querydsl-jap와 querydsl-apt가 필요합니다.
- Entity 클래스를 참고로 해서 자동 생성된 QClass가 저장될 디렉토리 설정이 필요합니다.
- querydsl-apt에 의해 자동 QClass는 querydsl로 작성된 쿼리 구문에서 table명과 field명의 역할을 합니다.