From 1d94be5efaa83c24596a8d76e870ac64ed663ee6 Mon Sep 17 00:00:00 2001 From: sumi Date: Sun, 14 Sep 2025 01:39:39 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=B6=94=EC=B2=9C=20=EB=A3=A8=ED=8A=B8?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=20API=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../route/controller/RouteController.java | 4 +-- .../route/repository/RouteRepository.java | 30 ++++++++++--------- .../domain/route/service/RouteService.java | 13 ++++---- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/mey/backend/domain/route/controller/RouteController.java b/src/main/java/com/mey/backend/domain/route/controller/RouteController.java index 4843576..79e013d 100644 --- a/src/main/java/com/mey/backend/domain/route/controller/RouteController.java +++ b/src/main/java/com/mey/backend/domain/route/controller/RouteController.java @@ -63,11 +63,11 @@ public CommonResponse startRoute( description = "추천 루트들을 조회한 결과를 반환합니다." )@GetMapping("/recommend") public CommonResponse getRecommendedRoutes( - @RequestParam(required = false) List themes, + @RequestParam(required = false) Theme theme, @RequestParam(defaultValue = "20") int limit, @RequestParam(defaultValue = "0") int offset) { - RouteRecommendListResponseDto response = routeService.getRecommendedRoutes(themes, limit, offset); + RouteRecommendListResponseDto response = routeService.getRecommendedRoutes(theme, limit, offset); return CommonResponse.onSuccess(response); } diff --git a/src/main/java/com/mey/backend/domain/route/repository/RouteRepository.java b/src/main/java/com/mey/backend/domain/route/repository/RouteRepository.java index ce14ece..9faf5e9 100644 --- a/src/main/java/com/mey/backend/domain/route/repository/RouteRepository.java +++ b/src/main/java/com/mey/backend/domain/route/repository/RouteRepository.java @@ -9,23 +9,23 @@ import java.util.List; public interface RouteRepository extends JpaRepository { - + // 특정 테마를 포함하는 루트 조회 @Query(value = "SELECT * FROM routes r WHERE JSON_CONTAINS(r.themes, JSON_QUOTE(:theme))", nativeQuery = true) List findByThemesContaining(@Param("theme") String theme); - - // 지역별 루트 조회 + + // 지역별 루트 조회 @Query("SELECT r FROM Route r WHERE r.region.nameKo = :regionName") List findByRegionName(@Param("regionName") String regionName); - + // 테마와 지역으로 필터링된 루트 조회 @Query(value = "SELECT r.* FROM routes r LEFT JOIN regions reg ON r.region_id = reg.region_id WHERE (:themes IS NULL OR JSON_OVERLAPS(r.themes, CAST(:themes AS JSON))) AND (:regionName IS NULL OR reg.name_ko = :regionName)", nativeQuery = true) List findByThemesAndRegion(@Param("themes") String themes, @Param("regionName") String regionName); - + // 여러 테마 중 하나라도 포함하는 루트 조회 @Query(value = "SELECT * FROM routes r WHERE JSON_OVERLAPS(r.themes, CAST(:themes AS JSON))", nativeQuery = true) List findByThemesContainingAny(@Param("themes") String themes); - + // 인기도순 정렬 (비용 기준으로 대체) @Query("SELECT r FROM Route r ORDER BY r.totalCost ASC") List findAllOrderByPopularity(); @@ -34,12 +34,14 @@ public interface RouteRepository extends JpaRepository { // POPULAR 전체 List findByRouteType(RouteType routeType); - // POPULAR + themes 조건 + // POPULAR + theme 조건 + @Query(value = """ - SELECT * - FROM routes r - WHERE r.route_type = 'POPULAR' - AND JSON_OVERLAPS(r.themes, CAST(:themesJson AS JSON)) - """, nativeQuery = true) - List findPopularByThemes(@Param("themesJson") String themesJson); -} + SELECT * FROM routes + WHERE route_type = 'POPULAR' + AND JSON_CONTAINS(themes, :themeJson) + ORDER BY id ASC + """, nativeQuery = true) + List findPopularByThemes(@Param("themeJson") String themeJson); + +} \ No newline at end of file diff --git a/src/main/java/com/mey/backend/domain/route/service/RouteService.java b/src/main/java/com/mey/backend/domain/route/service/RouteService.java index df9c128..4772009 100644 --- a/src/main/java/com/mey/backend/domain/route/service/RouteService.java +++ b/src/main/java/com/mey/backend/domain/route/service/RouteService.java @@ -219,15 +219,12 @@ private Totals computeTotals(List selected, List orderedPlaceIds) { private record Totals(int totalDurationSec, int totalDistanceMeters, int totalFare) { } - public RouteRecommendListResponseDto getRecommendedRoutes(List themes, int limit, int offset) { + public RouteRecommendListResponseDto getRecommendedRoutes(Theme theme, int limit, int offset) { List allRoutes; - if (themes != null && !themes.isEmpty()) { - // themes를 JSON 배열 문자열로 변환 - String themesJson = themes.stream() - .map(t -> "\"" + t.name() + "\"") // "FOOD", "CAFE" 이런 식으로 - .collect(Collectors.joining(",", "[", "]")); - + if (theme != null) { + // theme을 JSON 배열 문자열로 변환 (단일) + String themesJson = "[\"" + theme.name() + "\"]"; allRoutes = routeRepository.findPopularByThemes(themesJson); } else { allRoutes = routeRepository.findByRouteType(RouteType.POPULAR); @@ -409,4 +406,4 @@ public RouteCreateResponseDto createRoute(RouteCreateRequestDto request) { .regionName(savedRoute.getRegion() != null ? savedRoute.getRegion().getNameKo() : null) .build(); } -} +} \ No newline at end of file