JPA Native Query

이종윤·2022년 2월 15일
0

Spring JPA

목록 보기
21/23

Native Query 사용해보자.

    @Query(value = "select * from book", nativeQuery = true)
    List<Book> findAllCustom();	//

    @Transactional
    @Modifying
    @Query(value = "update book set category = 'IT전문서'", nativeQuery = true)
    int updateCategories();

    @Query(value = "show tables", nativeQuery = true)
    List<String> showTables();
  • 네이티브 쿼리는 JPQL과 다르게 Entity 속성들을 사용하지 못합니다.
  • select * from book 와 같이 테이블 이름이 들어간다. 다른 컬럼 이름을 적을때도 DB Table에서 쓰는 컬럼 이름을 적어야 한다.
    @Test
    void nativeQueryTest() {
//        bookRepository.findAll().forEach(System.out::println);
//        bookRepository.findAllCustom().forEach(System.out::println);

        List<Book> books = bookRepository.findAll();

        for (Book book : books) {
            book.setCategory("IT전문서");
        }

        bookRepository.saveAll(books);

        System.out.println(bookRepository.findAll());

        System.out.println("affected rows : " + bookRepository.updateCategories());
        bookRepository.findAllCustom().forEach(System.out::println);

        System.out.println(bookRepository.showTables());
    }
  • 현업에서는 네이티브 쿼리를 최소한으로 하는게 좋다. 운영중이나 Test 중에 오류가 생길수도 있기 때문이다. 그럼 네이티브 쿼리는 언제쓸까?
  • 첫번째는, 성능 이슈가 존재할때 쓴다. deleteAll쿼리가 모든 컬럼을 조회해서 하나하나씩 지우는 성능 이슈가 있었다. 그래서 나온게 deleteAllInBatch나 deleteInBatch이다. 하지만 update 쿼리는 없다. 그래서 하나하나 조회해서 update해야한다. 위 코드의 books를 불러와서 하나하나 "IT전문서" 카테고를 붙이면 성능이슈가 발생할 것이다. 그래서 deleteAllInBatch같이 한번에 할수있는 쿼리 ("update book set category = 'IT전문서'") 라고 해주면 된다. 이럴때 Native쿼리가 유용하다.
    - 이때 중요한건 DML작업에서는 @Modufying이라고 해서 update쿼리라고 표시해줘야한다.
    - 또한 Transaction이 필요하다. Native쿼리는 @Transactional을 직접 선언해 줘야 한다.
    - 하지만 @Transactional은 Spring에서 인터페이스보다 구체 클래스에 @Transactional을 다는걸 지향한다.
  • 두번째는, JPA에서 기본적으로 지원하지 않는 기능을 사용할때 쓴다. 위에있는 List showTables(); 같은 경우가 그렇다. 그럼 특수한 형태의 쿼리도 조회할수 있다.
profile
OK가자

0개의 댓글