개발/orm

Native Query 사용법

issac 2022. 3. 2. 15:59

1. @Query 어노테이션을 사용하여 NativeQuery를 사용한다.

  1). 일반적인 조회

@Query(value = "SELECT DISTINCT * FROM stock_search where searched_at BETWEEN DATE_ADD(NOW(), INTERVAL -1 MONTH) AND NOW() group By stock_id limit 10", nativeQuery = true)
List<StockSearch> searchPopularStocks();

 

  2). 파라미터를 받아서 사용하여 조회

@Query(value = "SELECT SUM(amount) FROM league_account_money where account_id = :accountId and league_id = :leagueId group by account_id, league_id", nativeQuery = true)
Integer sumAmount(@Param("accountId") Long accountId, @Param("leagueId") Long leagueId);

  3). Update 문 사용시에는 반드시 @Modifying 을 사용해야 한다.

@Modifying
@Query(value = "UPDATE point p SET p.status = 'CANCEL' , p.is_active = false WHERE p.account_id = :accountId AND p.type = 'DONGHAK'", nativeQuery = true)
void cancelDonghakPoint(Long accountId);

 

 

2. SQL문을 문자열로 직접작성해서 조회

  @Query 어노테이션 사용시 동적인 쿼리작성에 제한이 생겨 아래와같이 해결했다. 

  (초성 검색 기능을 넣었는데 Where절에 SQL문은 반환해주지만 @Query 안에 넣을 방법이 없었음..)

 

  1). QueryDSL을 사용해서 JPAQueryFactory 에 영속성 부여

@Configuration
public class QueryDSLConfig {

    @PersistenceContext
    private EntityManager entityManager;

    @Bean
    public JPAQueryFactory jpaQueryFactory(){
        return new JPAQueryFactory((entityManager));
    }

    public EntityManager entityManager(){
        return entityManager;
    }

}

  2).  쿼리문 작성 후 쿼리실행

String sql = "SELECT * FROM ";
Query nativeQuery = null;
sql += "stock s WHERE ";
sql += ChosungSearchQuery.searchSql(request.getWord(),"name");
sql += " OR ";
sql += ChosungSearchQuery.searchSql(request.getWord(),"id");
sql += " LIMIT " + request.getLimit() + " OFFSET " + request.getOffset();
nativeQuery = queryDSLConfig.entityManager().createNativeQuery(sql);
List<Object[]> stocks = nativeQuery.getResultList();
List<String> stockIds = stocks.stream().map(v -> v[0].toString()).collect(Collectors.toList());

※ 주의할점

 2번째 방법으로 네이티브 쿼리사용시 맵핑되지않아 Object로 반환해준다.