Native Query는 JPA와 무관하게, 실제 DB 쿼리문을 작성할 때 사용된다.
@Query 맨 뒤에 nativeQuery=true라고 설정만 해주면 된다.
또한 엔티티를 조회하던 JPQL 문법과 달리 DB에서 사용하는 테이블 기준 쿼리를 작성하면 된다.
@Query(value = "select * from book" , nativeQuery = true)
List<Book> findAllCustom();
@Test
void nativeQeuryTest() {
booKRepository.findAll().forEach(System.out::println);
bookRepository.findAllCustom().forEach(System.out::println);
}
@Query 메서드는 @Where을 감지해서 실행하지만, NativeQuery에서는 @Where가 포함되어 있지 않는다.
NativeQuery는 되도록이면 사용하지 않는데, DB에 따라서 실행이 안될 수 있다.
JPA에서는 deleteAllInBatch() 는 delete from book; 으로 한번에 삭제가 가능하다.
하지만, update는 한번에 가능하지 않고, 하나씩 save()를 해주어야 한다. 이럴 때 NativeQuery를 사용한다.
List<Book> books = bookRepository.findAll();
for(Book book : books) {
book.setCategory("IT서적");
}
bookRepository.saveAll(books);
book을 업데이트하기 위해서는 for문으로 하나씩 조회해서 업데이트를 해야 한다.
몇천만건을 한번에 가져와서 처리하는 것은 성능이슈가 있을 수 있다. 따라서 한번에 처리하는 것이 좋다. Native Query를 사용하면 된다.
public interface BookRepository extends JpaRepository<Book, Long> {
...
@Transactional
@Modifying
@Query(value = "update book set category = 'IT서적'", nativeQuery = true)
int updateCategories();
...
}
nativeQuery의 경우 트랜잭션을 직접 설정해주어야 하므로 @Transactional을 사용한다. 또한 @Modifying으로 업데이트라는 것을 알려준다. nativeQuery이므로 엔티티를 조회하는 것이 아니라, 테이블을 기준으로 작동한다. 리턴형이 int이면 업데이트 된 횟수를 리턴한다.
@Test
public void update() {
List<Book> books = bookRepository.findAll();
bookRepository.updateCategories();
}
nativeQuery로 하면 save()가 1개씩 모두 쿼리를 날렸던 것과 달리 하나의 쿼리만 나간다. (여전히 @Where는 무시한다.)
스프링 공식문서에는 구체적인 클래스, 혹은 구체적인 클래스의 메서드에 @Transactional을 사용하는 것을 권고한다. 혹은 인터페이스에 선언하고 싶다면 updateCategories()와 같이 프록시 interface에 정의한다.
마지막으로는 실제 사용하는 곳에서 @Transactional을 선언해야 한다.
@Transactional
@Test
public void update() {
List<Book> books = bookRepository.findAll();
bookRepository.updateCategories();
}
일반적인 JPA에서 제공하지 않는 정보들을 nativeQuery로 조회할 수 있다.
@Query(value = "show tables", nativeQuery = true)
List<String> showTables();
DB의 테이블 정보들을 조회할 수 있다.
@Test
public void showTables() {
bookRepository.showTables();
}
*정리
native Query는 JPA에서 제공하지 않는 정보들을 조회할 수 있고 update를 한번에 처리할 수 있는 장점이 있다. 하지만, 대부분 운영에서는 잘 사용하지 않기 때문에 대부분 쿼리는 JPA로 해결한다.
'학습 > DB' 카테고리의 다른 글
Converter 사용하기 (0) | 2021.09.30 |
---|---|
@Embedded, @Embedabble (0) | 2021.09.30 |
@Transactional (0) | 2021.09.26 |
고아제거 속성 알아보기 (0) | 2021.09.26 |
Cascade 활용하기 (0) | 2021.09.26 |