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 수정 시 쿼리 다시 - 안정성 미흡 - 유효성 검사 |
참고
728x90