ABOUT ME

-

오늘
-
어제
-
-
  • JPA - Common QueryDSL
    Back-end/JPA 2020. 6. 30. 17:16

    QueryDSL(Domain Specific Language)

    JPA를 사용하다보면 메소드 이름을 통해 자동으로 쿼리를 생성했었습니다.

    findByFirstNameIngoreCaseAndLastNameStartsWithIgnoreCase(String firstName, String lastName)

    위와 같은 네임을 가지고 있다면 가독성이 너무 떨어질 뿐더러 쿼리가 추가될 때마다 여러 조건들이 추가될 것입니다.
    하지만 QueryDSL을 사용하게 되면 타입세이프하게 쿼리를 만들어 사용할 수 있습니다.

    홈페이지 : querydsl

    연동 방법

    기본 리포지토리 커스터마이징 안 했을 때

    querydsl

    먼저 Account 엔티티와 JpaRepository를 상속받는 Repository를 생성합니다.

    querydsl

    그리고 빈 주입 테스트를 하기 위해 테스트를 실행합니다.
    여기서 이상이 없다면 성공하게 됩니다! 이제 의존성플러그인을 추가해보겠습니다.

    의존성 추가

    <dependency>
      <groupId>com.querydsl</groupId>
      <artifactId>querydsl-apt</artifactId>
    </dependency>
    <dependency>
      <groupId>com.querydsl</groupId>
      <artifactId>querydsl-jpa</artifactId>
    </dependency>

     

    querydsl

    의존성을 추가해줍니다. QueryDSL은 스프링 부트가 의존성을 관리해주므로 버전을 명시하지 않아도 됩니다.
    apt모듈은 QueryDSL이 Entity모델을 보고 Query용 Specific Language(특정 언어)를 만들어 주는 모듈입니다.

    플러그인 추가

    <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>

     

    querydsl

    빌드하면 target/generated-sources/java에 클래스를 생성하겠며, JPA를 사용하겠다는 의미입니다.
    레퍼런스참고

    querydsl

    위와 같이 의존성을 다 추가한 다음 Maven - Lifecycle - compile 클릭해서 빌드하게 되면

    querydsl

    빌드 성공시 플러그인에 선언했던 경로에 생성된 것을 볼 수 있습니다.

    생성된 클래스가 자동완성이 안된다면?

    여기에 생성된 QAccount 클래스가 만약 자동완성이 안되는 경우가 생긴다면 어떻게 해야할까요?

    querydsl

    Project Structure에 들어가 해당 경로를 Sources로 바꾸어주면 해결됩니다.

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

     

    querydsl

    Repository에 QuerydslPredicateExecutor<T>를 상속받습니다. 타입에는 엔티티를 넣어주면 됩니다.

    import com.querydsl.core.types.Predicate;
    
    @RunWith(SpringRunner.class)
    @DataJpaTest
    public class AccountRepositoryTest {
    
        @Autowired
        AccountRepository accountRepository;
    
        @Test
        public void crud() {
            Predicate predicate = QAccount.account
                    .firstName.containsIgnoreCase("junjang")
                    .and(QAccount.account.lastName.startsWith("kim"));
    
            Optional<Account> one = accountRepository.findOne(predicate);
            assertThat(one).isEmpty();
        }
    }

     

    querydsl

    querydsl predicate를 생성하여 생성된 QAccount 객체로 쿼리를 작성하여 테스트 합니다.

    기본 리포지토리 커스터마이징 했을 때

    기본 구현 리포지토리가 아닌 커스텀한 리포지토리 구현체에 QuerydslPredicateExecutor<T>를 상속받고 생성자를 생성해주면 됩니다.

    'Back-end > JPA' 카테고리의 다른 글

    JPA - Common Pageable, Sort  (0) 2020.06.30
    JPA - Common DomainClassConverter  (0) 2020.06.30
    JPA - Common BasicRepository  (0) 2020.06.30
    JPA - Common CustomRepository  (0) 2020.06.30
    JPA - Common Query  (0) 2020.06.30

    댓글