[Spring Data JPA] JPQL

sohee·2022년 12월 1일
0
post-thumbnail

Overview

JPA를 사용하여 서비스를 구현하다 보면 JPA의 Query Methods 만으로는 조회가 불가능한 경우가 존재한다.
이러한 경우 JPQL(Java Persistence Query Language)를 이용한 쿼리를 작성하여 조회를 할 수 있다.
JPQL을 작성하기 위한 방법으로 @Query annotation을 이용하여 JPQL을 작성하는 방법과, Native Query에 대해 적어보려고 한다.

@Query

@Query annotation은 더 구체적인 쿼리 메소드를 작성하기 위해 사용하며,기본적으로 JPA에서 사용하는 쿼리 문법인 JPQL을 사용한다.

Entity

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Stock {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Long productId;
    private Long quantity;
}

Repository

public interface StockRepository extends JpaRepository<Stock, Long> {

    @Query("select s from Stock s where s.id = :id")
    Stock findByIdWithPessimisticLock(Long id);
}

위와 같이 Entity의 JpaRepository를 상속받는 인터페이스에 정의할 수 있다.
JPA의 Entity를 기반으로 하는 쿼리를 생성해주기 때문에 쿼리에 Table Name이 아닌 Entity이름이 들어간다. 또한 쿼리에 들어가는 내용은 엔티티 내에 있는 field의 이름을 가리킨다. 기본적으로 from 구문에 Entity의 객체를 선언하여 해당 객체의 속성명을 통해서 조건과 파라미터를 전달한다.

Query annotation을 이용한 DTO반환

여러개의 Entity의 속성이 정의되어 있는 DTO를 반환하기 위해서는 SELECT에서 해당 DTO의 생성자를 생성하는 코드를 적어주면 된다.

DTO

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class StockDto {
    private Long id;
    private Long productId;
    private Long quantity;
}

Repository

public interface StockRepository extends JpaRepository<Stock, Long> {

    @Query(value = "select " +
            "new StockDto(s.id, s.productId, s.quantity) " +
            "from Stock s " +
            "left outer join Product p on s.productId = p.id ")
    Stock findProductStock(Long id);
}

Native Query

Native Query는 DB에서 사용하는 SQL문을 그대로 사용할 수 있게 해 준다.

public interface LockRepository extends JpaRepository<Stock, Long> {

    @Query(value = "select get_lock(:key, 3000)", nativeQuery = true)
    void getLock(String key);
}

위와 같이, nativeQuery옵션을 true로 사용하면 entity가 아닌 table을 사용하게 되며 field의 이름도 table의 column명을 써야 한다.

장점: JPA의 쿼리 메서드는 여러 데이터를 업데이트 할때 update query를 여러번 실행시키지만 native query는 한 번의 query로 update처리가 가능하다.

단점: Native Query는 특정 DB에 의존성을 가진 쿼리를 만들게 된다.
Database 종류로부터 자유롭다는 JPA의 장점에 어긋나므로 JPA를 사용하면서 Native Query 또한 사용하는 것은 지양해야 한다.

profile
기억하려고 적는 개발 로그🌞

0개의 댓글