JPA와 사용자 정의 쿼리

Lee InnJie·2022년 6월 26일
0

JPA Repository에서 지원하지 않는 쿼리를 사용하려면 사용자 정의 쿼리를 구현해야 한다.
사용자 정의 쿼리를 구현하기 위해서는

  1. JPQL을 작성해 쿼리를 실행
  2. @Query를 사용해 사용할 메소드 위에 정의

의 두 가지 방법이 있다.

JPQL (Java Persistence Query Language)

SQL과 JPQL에는 차이점이 있다.

SQL
테이블을 대상으로 쿼리 실행

JPQL
엔티티를 대상으로 쿼리 실행

JPQL의 특징

JPQL에는 몇가지 특징이 있다.

  1. 대소문자 구분
    엔티티와 속성에 대해서 대소문자를 구분한다.
  2. 엔티티 명시
    JPQL에서 사용한 Booktbl은 엔티티다. 엔티티명은 DTO에서 @Entity(name='name')의 형식으로 지정할 수 있다.
  3. 별칭 필수
    위 예제 속 jstl의 dBooktbl이라는 엔티티의 별칭이다. 이 별칭을 필수적으로 지정해야 한다.

TypedQuery와 Query

JPQL을 실행하기 위한 객체를 만들어야 한다.

TypedQuery
반환 타입이 명확함

Query
반환 타입이 명확하지 않음

예시는 다음과 같다.

Service

    @PersistenceContext
    private EntityManager em;
    
    //jpql 작성
    String jpql = "select d from Booktbl d";
    public List<BookDTO> getBookList() {
    	//쿼리를 실행하기 위한 객체 생성
        TypedQuery<BookDTO> query = em.createQuery(jpql, BookDTO.class);
        List<BookDTO> bookList = query.getResultList();
        return bookList;
    }

DTO

@Entity (name="Booktbl")
public class BookDTO {
    @NotNull
    @Id
    @GeneratedValue
    @Column(name = "idx")
    private long idx;

    @NotNull
    @Column(name = "title")
    private String title;

    @NotNull
    @Column(name = "author")
    private String author;
}

@Query

@Query는 JPARepository를 상속하는 인터페이스에서 사용한다.
사용자 지정 쿼리를 만들기 위해 파라미터 바인딩을 하는데, 두 가지 방법이 있다.
그리고 테이블 기준으로 쿼리를 작성하기 위해서는 nativeQuery = true 옵션을 주면 된다.

위치 기준 바인딩
JDBC의 ResultSet과 비슷하다. 하지만 위치 기반이기 때문에 위치를 잘못 기재하여 발생하는 오류와 수정이 어렵기 때문에 이름 기준 바인딩을 주로 사용한다.
SELECT m FROM Member m WHERE m.username = ?0

이름 기준 바인딩
파라미터의 이름을 기준으로 바인딩한다.
@Query("select u from User u where u.username = :name")

예시는 다음과 같다.

Repository

public interface BookRepository extends JpaRepository<BookDTO, Integer> {
    @Query(value = "SELECT * FROM BookTbl", nativeQuery = true)
    List<BookDTO> getAllBookList();

    @Query(value = "SELECT * FROM Booktbl WHERE idx > :idx", nativeQuery = true)
    BookDTO getBookById(long idx);
}
profile
⌒_⌒

0개의 댓글