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로 반환해준다.