본문 바로가기
Java, Kotlin, Spring/JPA

Spring Data Common - QueryDSL

by Wordbe 2021. 2. 10.
728x90

쿼리 메소드는 대부분 두 가지 중 하나로 결정된다.

  • Optional<T> findOne(Predicate) : 어떤 조건으로 1개를 찾는다.
  • List<T>|Page<T>|Iterable<T> ... findAll(Predicate) : 어떤 조건으로 여러개를 찾는다.
  • 스프링 데이터는 QuerydslPredicateExecutor 인터페이스를 제공한다. 여러 메소드가 있지만 위의 2가지가 대표적이다.

너무 긴 쿼리메소드는 무엇을 실행시키는지 읽기가 너무 어렵다 그래서 쿼리 DSL 을 사용한다.

QueryDSL

query domain specific lanaguage (쿼리 도메인 특화 언어) 를 말한다.

타입-세이프한 쿼리를 만들 수 있도록 돕는 라이브러리이다. JPA, SQL, MongoDB, JDO, Lucene, Collection 을 지원한다.

QueryDSL 을 사용해보자.

우선 메이븐에 의존성을 추가한다.


  
<!-- QueryDSL -->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>

  
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<!-- QueryDSL -->
<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>

이렇게 의존성을 추가해주었다면, 꼭 maven 을 compile 해주자. 인텔리제이에서는 maven 탭에서 컴파일을 더블클릭해주면 된다.

 

엔티티와 레포지토리를 만든다.


  
@Getter @Setter
@Entity
public class Account {
@Id @GeneratedValue
private Long id;
private String username;
private String firstName;
private String lastName;
}

레포지토리에는 QuerydslPredicateExecutor를 같이 상속받으면 된다.


  
public interface AccountRepository extends JpaRepository<Account, Long>, QuerydslPredicateExecutor<Account> {
}

간단한 테스트를 만들어보자.


  
@DataJpaTest
class AccountRepositoryTest {
@Autowired
AccountRepository accountRepository;
@Test
public void crud() {
Predicate predicate = QAccount.account.firstName.containsIgnoreCase("Dorsey")
.and(QAccount.account.lastName.startsWith("Jack"));
Optional<Account> one = accountRepository.findOne(predicate);
assertThat(one).isEmpty();
}
}

주의할 점은 Predicate 를 자동완성할 때 querydsl 것을 불러오자.

위 QueryDSL 은 findByFirstNameIngoreCaseAndLastNameStartsWithIgnoreCase 라는 쿼리메소드를 조금 더 읽기 편하게 만들어주었다.

 

 

 

- 백기선님 스프링 데이터 JPA 참고

728x90

댓글