Web/SpringBoot

[SpringBoot] 쿼리 메소드 vs JPQL vs QueryDsl vs NativeQuery

깨구르르 2024. 4. 19. 16:07
728x90

1. JPA(Query Method) 쿼리 메소드

 

사용하려는 Repository에 JpaRepository만 상속해주면 스프링 AOP 기능을 사용해 구현까지 자동으로 해준다.

간단한 문법으로 객체의 CRUD가 가능하다.

  • 형태: find + ("객체") + By + "변수"
  • 사용 예시
Board findById(Integer Id)
// -> id를 사용해서 해당하는 게시글을 가져온다.

List<Board> findByTitle(String title)
// -> title 변수명을 사용해서 해당하는 모든 게시글을 가져온다.
  • 장점
    • 개발자가 사용하기 쉽도록 자동으로 쿼리를 만들어줌
    • 기본(Hibernate)으로 쿼리를 자동 생성함
  • 단점
    • 쿼리 작성에 유연하지 않음
    • 복잡한 조건을 사용하려면 메소드의 길이가 증가
    • 매핑하여 사용하므로 DB에 직접적으로 쿼리를 실행하는 NativeQuery보다 속도가 느림

 


 

2. JPQL

 

Java Persistence Query Language

복잡한 조건을 메소드로 표현하기 어려울 수 있기 때문에  JPQL을 사용해 직접 쿼리문을 작성하여 객체를 조회할 수 있다.

객체를 대상으로 하는 쿼리문이며 SQL을 추상화해서 사용한다.

  • 형태: @Query(" query문 ")
  • 사용 예시
@Query("select b from Board b where b.title like concat('%', :keyword, '%')")
Page<Board> findKeyWord(String keyword, Pageable pageable);

// -> keyWord가 포함된 문자열로 게시글 검색(%keyword%)
  • 장점
    • 특정 유형의 DB에 연결된 것이 아니기 때문에 DB 변경 시에도 유지, 보수 부분에서 유연하며 쿼리를 다시 작성할 필요가 없음
    • 반환 유형을 지정할 수 있음
    • 코드 실행 단계가 아닌 코드를 작성하는 시점에서 빠르게 오류를 발견할 수 있음
  • 단점
    • 여러 조인이나 복잡한 쿼리를 작성해야 할 때 어려움
    • 직접 쿼리문을 문자열로 작성하기 때문에 오타로 인한 컴파일 에러를 통해 확인이 불가능
    • JPQL만의 SQL문 작성 방법을 새로 공부해서 쿼리문을 작성해야 함
    • 매핑하여 사용하므로 DB에 직접적으로 쿼리를 실행하는 NativeQuery보다 속도가 느림

 


 

3. QueryDsl

 

QueryDsl은 쿼리문을 소스코드를 사용해서 작성한다.

가독성이 높고 확장 가능한 동적쿼리를 작성하기 위해 Querydsl을 사용한다.

  • 사용 예시
    : 아래 코드는 Querydsl을 사용하여 JPQL을 생성하는 방식으로 구현한 것
public Page<Board> search1(Pageable pageable) {

    // Querydsl을 사용해서 Board Entity에 대한 쿼리를 생성하기 위해 Q 타입 사용
    QBoard board = QBoard.board;

    /* Querydsl을 통해서 한 단계씩 sql문을 작성 */

    // select * from board
    JPQLQuery<Board> query = from(board);

    // where title like '%1%'
    query.where(board.title.contains("1"));

    // 페이징을 적용하기 위해 .applyPagination 사용
    // 주어진 Pagealbe 객체를 사용하여 쿼리에 페이징 및 정렬 정보를 적용함
    // order by bno desc limit 1, 10;
    this.getQuerydsl().applyPagination(pageable, query);

    // select * from board where title like '%1%' order by bno desc limit 1, 10;
    // 쿼리를 실행하고 결과를 가져옴
    List<Board> list = query.fetch();

    // select count(bno) from board where title like '%1%';
    long count = query.fetchCount();
}
  • 장점
    • IDE를 통한 자동완성 기능
    • 문자가 아닌 코드로 쿼리 작성 👉 컴파일 에러가 발생해 확인 가능
    • 조건문을 사용한 동적 쿼리문 작성이 간편
    • 쿼리 작성 시 제약 조건 등을 메서드 추출을 통해 코드의 재사용성 증가
  • 단점
    • 설정이 어려움

 


 

4. NativeQuery

 

데이터베이스에 직접적인 쿼리를 실행하는 방법이다.

사용하는 DBMS에 따라 조금씩 차이가 있다.

  • 형태: @Query(" query문 ", nativeQuery = true)
  • 사용 예시
@Query(value = "select now()", nativeQuery = true)
String getTime();
  • 장점
    • DB에 직접적으로 쿼리를 실행시켜 속도가 빠름
    • SQL 언어를 전체적으로 사용 가능
    • 여러 조인이나 복잡한 쿼리를 작성할 때 직관적이며 이해가 쉬움
  • 단점
    • 특정 DB에 대해 쿼리를 작성하기에 종속성이 높아질 수 있고 DB가 수정되면 쿼리를 다시 만들어야 함
    • 결과를 Object 리스트로 반환하기에 JPQL의 TypeQuery보다 안정성 부분에서 미흡
    • 사용자에게 입력된 값매개변수로 바인딩하거나 따로 유효성 검사가 필요할 수 있음

 


 

비교

 

  Query Method JPQL QueryDsl NativeQuery
장점 - 자동으로 쿼리 생성
- 기본으로 쿼리를 자동 생성
- 유지보수 유연함
- 반환 유형 지정 가능
- 코드 작성 시점에 오류 발견
- 자동완성
- 컴파일에러 확인 가능
- 동적 쿼리문 작성 간편
- 코드의 재사용성 증가
- 속도 빠름
- SQL 언어 전체적 사용
- 직관적, 이해 쉬움
단점 - 쿼리 작성에 유연 X
- 복잡한 조건 사용 시 메소드 길이 증가
- 속도 느림
- 조인, 복잡한 쿼리 작성 어려움
- 컴파일 에러 확인 불가
- SQL문 작성법 새로 공부
- 속도 느림
- 설정이 어려움 - DB 수정 시 쿼리 다시
- 안정성 미흡
- 유효성 검사

 


 

참고

 

https://rhdqors.tistory.com/51

https://velog.io/@simgyuhwan/%EC%BF%BC%EB%A6%AC-%EB%A9%94%EC%86%8C%EB%93%9C-JPQL-Querydsl-%EC%9A%94%EC%95%BD

728x90