타인의 향수를 추천해주는 기능은 선택된 향수 중에서 1가지를 선택하여 상대방에게 제시되는 기능입니다.
조합에 맞는 향수들을 모두 고른 뒤 그 중에서 1가지의 향수를 랜덤 선택하여 제시하는 로직이기 때문에, 불필요하게 쿼리수가 나간다는 단점이 있었습니다.
결국 사용되지 않는 자원임에도 불구하고 쿼리가 많이 발생되어 트래픽이 증가하면 부하가 발생할 것이라고 판단되었습니다.
@Query("SELECT s FROM survey s WHERE s.genderAnswer LIKE %:genderAnswer% AND s.scentAnswer = :scentAnswer AND s.moodAnswer LIKE %:moodAnswer% AND s.styleAnswer LIKE %:styleAnswer%")
List<Survey> findSurveysByGenderScentMoodAndStyle(@Param("genderAnswer") String genderAnswer,
@Param("scentAnswer") String scentAnswer,
@Param("moodAnswer") String moodAnswer,
@Param("styleAnswer") String styleAnswer);
이전 설문을 통한 향수 추천 로직과 동일한 코드를 그대로 사용하였기 때문에 여러가지 향수 리스트가 추천되었습니다.
향수가 하나만 추천될 수 있도록 새로운 메서드를 정의했습니다.
@Query(value = "SELECT * FROM survey s WHERE s.gender_answer LIKE :genderAnswer AND s.scent_answer = :scentAnswer AND s.mood_answer LIKE :moodAnswer AND s.season_answer LIKE :seasonAnswer AND s.style_answer LIKE :styleAnswer ORDER BY RAND() LIMIT 1", nativeQuery = true)
Optional<Survey> findSurveysByRecommend(@Param("genderAnswer") String genderAnswer,
@Param("scentAnswer") String scentAnswer,
@Param("moodAnswer") String moodAnswer,
@Param("seasonAnswer") String seasonAnswer,
@Param("styleAnswer") String styleAnswer);
JPQL에서는 ORDER BY RAND()와 LIMIT 구문을 직접 지원하지 않습니다. 따라서 네이티브 쿼리를 사용하였습니다.
JPA에서 네이티브 쿼리를 사용하려면 @Query 어노테이션 내에 'nativeQuery = true'를 추가해주면 됩니다.
여기까지 한 상태로 쿼리를 실행시켰는데 향수 조회가 되지 않았습니다.
JPA에서는 '%'를 통해 문자열 부분 포함 여부를 선택할 수 있는데 네이티브 쿼리에서는 이를 지원하지 않았습니다.
따라서 파라미터 요청을 할때 '%' 값을 추가하도록 파싱하는 메서드를 request내에 추가시켜주었습니다.
public void addQueryParameter() {
this.genderAnswer = "%" + genderAnswer + "%";
this.moodAnswer = "%" + moodAnswer + "%";
this.seasonAnswer = "%" + seasonAnswer + "%";
this.styleAnswer = "%" + styleAnswer + "%";
}
이렇게 수정한 후에 실행을 해보았습니다.
쿼리수가 줄게 되었습니다!!