diff --git a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/application/DashBoardService.java b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/application/DashBoardService.java index 99856e12..a65915fb 100644 --- a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/application/DashBoardService.java +++ b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/application/DashBoardService.java @@ -1,7 +1,6 @@ package kernel360.trackyweb.dashboard.application; import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -9,12 +8,13 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StopWatch; import kernel360.trackycore.core.common.api.ApiResponse; -import kernel360.trackycore.core.domain.entity.GpsHistoryEntity; import kernel360.trackycore.core.domain.entity.MonthlyStatisticEntity; import kernel360.trackycore.core.domain.entity.RentEntity; import kernel360.trackycore.core.domain.entity.enums.RentStatus; +import kernel360.trackycore.core.domain.provider.BizProvider; import kernel360.trackycore.core.domain.provider.RentProvider; import kernel360.trackyweb.car.domain.provider.CarDomainProvider; import kernel360.trackyweb.dashboard.application.dto.response.DashboardCarStatusResponse; @@ -33,6 +33,7 @@ @RequiredArgsConstructor public class DashBoardService { private final DashGpsHistoryProvider dashGpsHistoryProvider; + private final BizProvider bizProvider; private final CarDomainProvider carDomainProvider; private final RentProvider rentProvider; private final RentDomainProvider rentDomainProvider; @@ -90,28 +91,33 @@ public DashboardStatisticsResponse getStatistics(String bizUuid) { * @return 구역 : 차량 수 map */ @Transactional(readOnly = true) - public Map> getGeoData(String bizUuid) { + public Map getGeoData(String bizUuid) { - List gpsList = dashGpsHistoryProvider.findLatestGps(bizUuid); + Long bizId = bizProvider.getBiz(bizUuid).getId(); - log.info("gpsList: {} ", gpsList); + // Map map = dashGpsHistoryProvider.findLatestGps(bizId); // 개선 전 + Map map = dashGpsHistoryProvider.findLatestLatLon(bizId); // 개선 후 - Map> provinceCountMap = new HashMap<>(); + int[] lats = map.get("lats"); + int[] lons = map.get("lons"); - for (GpsHistoryEntity gps : gpsList) { + Map provinceCountMap = new HashMap<>(); + + StopWatch st = new StopWatch(); + st.start("provinceMatcher"); + + for (int i = 0; i < lats.length; i++) { // DB에 저장된 위도/경도는 정수형이므로 소수로 변환 필요 - double lat = gps.getLat() / 1_000_000.0; - double lon = gps.getLon() / 1_000_000.0; + double lat = lats[i] / 1_000_000.0; + double lon = lons[i] / 1_000_000.0; String province = provinceMatcher.findProvince(lon, lat); - String mdn = gps.getDrive().getCar().getMdn(); - - provinceCountMap - .computeIfAbsent(province, k -> new ArrayList<>()) - .add(mdn); + provinceCountMap.put(province, provinceCountMap.getOrDefault(province, 0) + 1); } - log.info("처리된 GPS 데이터: {}개", gpsList.size()); + st.stop(); + log.info("{}", st.prettyPrint()); + log.info("provinceCountMap: {}", provinceCountMap); return provinceCountMap; } diff --git a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/domain/projection/GpsLatLonProjection.java b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/domain/projection/GpsLatLonProjection.java new file mode 100644 index 00000000..3c3745e6 --- /dev/null +++ b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/domain/projection/GpsLatLonProjection.java @@ -0,0 +1,8 @@ +package kernel360.trackyweb.dashboard.domain.projection; + +public interface GpsLatLonProjection { + + Double getLat(); + + Double getLon(); +} diff --git a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/domain/provider/DashGpsHistoryProvider.java b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/domain/provider/DashGpsHistoryProvider.java index 3cf5b34d..91427bb8 100644 --- a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/domain/provider/DashGpsHistoryProvider.java +++ b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/domain/provider/DashGpsHistoryProvider.java @@ -1,20 +1,70 @@ package kernel360.trackyweb.dashboard.domain.provider; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.springframework.stereotype.Component; +import org.springframework.util.StopWatch; -import kernel360.trackycore.core.domain.entity.GpsHistoryEntity; +import com.querydsl.core.Tuple; + +import kernel360.trackyweb.dashboard.domain.projection.GpsLatLonProjection; import kernel360.trackyweb.dashboard.infrastructure.repository.DashGpsHistoryRepository; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; @Component @RequiredArgsConstructor +@Slf4j public class DashGpsHistoryProvider { private final DashGpsHistoryRepository dashGpsHistoryRepository; - public List findLatestGps(String bizUuid) { - return dashGpsHistoryRepository.getLatestGps(bizUuid); + public Map findLatestGps(Long bizId) { + + StopWatch st = new StopWatch("findLatestGps"); + st.start(); + List response = dashGpsHistoryRepository.getLatestGps(bizId); + st.stop(); + + log.info("{}", st.prettyPrint()); + + int[] lats = new int[response.size()]; + int[] lons = new int[response.size()]; + + for (int i = 0; i < response.size(); i++) { + lats[i] = response.get(i).get(0, Integer.class); + lons[i] = response.get(i).get(1, Integer.class); + } + + return new HashMap<>() {{ + put("lats", lats); + put("lons", lons); + }}; + } + + public Map findLatestLatLon(Long bizId) { + + StopWatch st = new StopWatch("findLatestByNativeQuery"); + st.start(); + List latLons = dashGpsHistoryRepository.findLatestLatLonByBizId(bizId); + st.stop(); + + log.info("{}", st.prettyPrint()); + + int[] lats = new int[latLons.size()]; + int[] lons = new int[latLons.size()]; + + for (int i = 0; i < latLons.size(); i++) { + GpsLatLonProjection latLon = latLons.get(i); + lats[i] = latLon.getLat().intValue(); + lons[i] = latLon.getLon().intValue(); + } + + return new HashMap<>() {{ + put("lats", lats); + put("lons", lons); + }}; } } diff --git a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepository.java b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepository.java index 05b034ab..b0601140 100644 --- a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepository.java +++ b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepository.java @@ -1,10 +1,43 @@ package kernel360.trackyweb.dashboard.infrastructure.repository; +import java.util.List; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import kernel360.trackycore.core.infrastructure.repository.GpsHistoryRepository; +import kernel360.trackyweb.dashboard.domain.projection.GpsLatLonProjection; @Repository public interface DashGpsHistoryRepository extends GpsHistoryRepository, DashGpsHistoryRepositoryCustom { + @Query(value = """ + WITH latest_seq AS ( + SELECT + gh2.drive_id, + MAX(gh2.drive_seq) AS max_seq + FROM gpshistory gh2 + GROUP BY gh2.drive_id + ), latest_drive AS ( + SELECT mdn, MAX(d3.id) AS max_drive + FROM drive d3 + GROUP BY d3.mdn + ) + SELECT + gh.lat, gh.lon + FROM latest_seq ls + JOIN latest_drive ld + ON ld.max_drive = ls.drive_id + JOIN gpshistory gh + ON gh.drive_id = ld.max_drive + AND gh.drive_seq = ls.max_seq + JOIN car c + ON c.mdn = ld.mdn + AND c.biz_id = :bizId + GROUP BY c.mdn + """, + nativeQuery = true + ) + List findLatestLatLonByBizId(@Param("bizId") Long bizId); } diff --git a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepositoryCustom.java b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepositoryCustom.java index 61e58911..55cfe5bf 100644 --- a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepositoryCustom.java +++ b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepositoryCustom.java @@ -2,8 +2,8 @@ import java.util.List; -import kernel360.trackycore.core.domain.entity.GpsHistoryEntity; +import com.querydsl.core.Tuple; public interface DashGpsHistoryRepositoryCustom { - List getLatestGps(String bizUuid); + List getLatestGps(Long bizId); } diff --git a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepositoryCustomImpl.java b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepositoryCustomImpl.java index d294a5f3..5ed1fb1d 100644 --- a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepositoryCustomImpl.java +++ b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/infrastructure/repository/DashGpsHistoryRepositoryCustomImpl.java @@ -1,6 +1,5 @@ package kernel360.trackyweb.dashboard.infrastructure.repository; -import static kernel360.trackycore.core.domain.entity.QBizEntity.*; import static kernel360.trackycore.core.domain.entity.QCarEntity.*; import static kernel360.trackycore.core.domain.entity.QDriveEntity.*; import static kernel360.trackycore.core.domain.entity.QGpsHistoryEntity.*; @@ -9,10 +8,11 @@ import org.springframework.stereotype.Repository; +import com.querydsl.core.Tuple; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQueryFactory; +import com.zaxxer.hikari.HikariDataSource; -import kernel360.trackycore.core.domain.entity.GpsHistoryEntity; import lombok.RequiredArgsConstructor; @Repository @@ -20,17 +20,18 @@ public class DashGpsHistoryRepositoryCustomImpl implements DashGpsHistoryRepositoryCustom { private final JPAQueryFactory queryFactory; + private final HikariDataSource ds; /** * 대시보드 차량 위치 지도 - 업체별 최신 GPS 조회 - * @param bizUuid + * @param bizId * @return */ @Override - public List getLatestGps(String bizUuid) { + public List getLatestGps(Long bizId) { return queryFactory - .select(gpsHistoryEntity) + .select(gpsHistoryEntity.lat, gpsHistoryEntity.lon) .from(gpsHistoryEntity) .join(gpsHistoryEntity.drive, driveEntity) .where( @@ -40,8 +41,7 @@ public List getLatestGps(String bizUuid) { .select(driveEntity.id.max()) .from(driveEntity) .join(driveEntity.car, carEntity) - .join(carEntity.biz, bizEntity) - .where(bizEntity.bizUuid.eq(bizUuid)) + .where(carEntity.biz.id.eq(bizId)) .groupBy(carEntity.mdn) ) ) diff --git a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/presentation/DashBoardController.java b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/presentation/DashBoardController.java index b5bcd736..1b437c98 100644 --- a/tracky-web/src/main/java/kernel360/trackyweb/dashboard/presentation/DashBoardController.java +++ b/tracky-web/src/main/java/kernel360/trackyweb/dashboard/presentation/DashBoardController.java @@ -51,10 +51,10 @@ public ApiResponse updateStatusToReturn(@PathVariable String rentUuid) { } @GetMapping("/geo") - public ApiResponse>> getGeoData( + public ApiResponse> getGeoData( @Schema(hidden = true) @AuthenticationPrincipal MemberPrincipal memberPrincipal ) { - Map> geoMap = dashBoardService.getGeoData(memberPrincipal.bizUuid()); + Map geoMap = dashBoardService.getGeoData(memberPrincipal.bizUuid()); return ApiResponse.success(geoMap); } }