JPA의 쿼리 메서드 기능과 @Query를 통해서 많은 기능을 구현할 수 있지만, 선언할 때 고정된 형태의 값을 가진다는 단점이 있다. 이 때문에 단순한 몇 가지의 검색 조건을 만들어야 하는 상황에서는 기본 기능만으로 충분하지만, 복잡한 조합을 이용하는 경우의 수가 많은 상황에서는 동적으로 쿼리를 생성해서 처리할 수 있는 기능이 필요하다.
코드 내부에서 상황에 맞는 쿼리를 생성할 수 있게 된다. 하지만 이를 위해서는 작성된 엔티티 클래스를 그대로 이용하는 것이 아닌 'Q도메인'이라는 것을 이용해야한다.
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.2'
id 'io.spring.dependency-management' version '1.1.6'
}
group = 'org.zerock'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'com.querydsl:querydsl-jpa:5.1.0:jakarta'
annotationProcessor(
"jakarta.persistence:jakarta.persistence-api",
"jakarta.annotation:jakarta.annotation-api",
'com.querydsl:querydsl-apt:5.1.0:jakarta'
)
}
tasks.named('test') {
useJUnitPlatform()
}

build.gradle 파일을 수정하고 프로그램을 시작하면 build 폴더 내에 generated 폴더가 생성된 것을 확인할 수 있고, 내부에는 Q로 시작하는 파일들이 생성된 것을 확인할 수 있다.

Querydsl의 사용법
@Test
public void testQuery1() {
Pageable pageable = PageRequest.of(0, 10, Sort.by("gno").descending());
QGuestbook qGuestbook = QGuestbook.guestbook; // 1
String keyword = "1";
BooleanBuilder builder = new BooleanBuilder(); // 2
BooleanExpression expression = qGuestbook.title.contains(keyword); // 3
builder.and(expression); // 4
Page<Guestbook> result = guestbookRepository.findAll(builder, pageable); // 5
result.stream().forEach(guestbook -> System.out.println(guestbook));
}
com.querydsl.core.types.Predicate 타이이어야 한다.QuerydslPredicateExcutor 인터페이스와 findAll()을 사용할 수 있다.결과값

@Test
public void testQuery2() {
Pageable pageable = PageRequest.of(0, 10, Sort.by("gno").descending());
QGuestbook qGuestbook = QGuestbook.guestbook;
String keyword = "1";
BooleanBuilder builder = new BooleanBuilder();
BooleanExpression exTitle = qGuestbook.title.contains(keyword);
BooleanExpression exContent = qGuestbook.content.contains(keyword);
BooleanExpression exAll = exTitle.or(exContent);
builder.and(exAll);
builder.and(qGuestbook.gno.gt(0L));
Page<Guestbook> result = guestbookRepository.findAll(builder, pageable);
result.stream().forEach(guestbook -> System.out.println(guestbook));
}