diff --git a/src/main/java/com/nainga/nainga/domain/store/application/GoodPriceGoogleMapStoreService.java b/src/main/java/com/nainga/nainga/domain/store/application/GoodPriceGoogleMapStoreService.java index b4e036e0..b5b45d16 100644 --- a/src/main/java/com/nainga/nainga/domain/store/application/GoodPriceGoogleMapStoreService.java +++ b/src/main/java/com/nainga/nainga/domain/store/application/GoodPriceGoogleMapStoreService.java @@ -24,9 +24,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.util.*; import static com.nainga.nainga.domain.store.application.GoogleMapMethods.*; @@ -78,10 +76,10 @@ public void createAllGoodPriceStores(String fileName) { //WKTReader Parse exception에 대한 처리를 위한 try-catch문 try { - List regularOpeningHours; - List weekdayDescriptions = new ArrayList<>(); - List localPhotosList = new ArrayList<>(); - List googlePhotosList = new ArrayList<>(); + Set regularOpeningHours; + Set weekdayDescriptions = new LinkedHashSet<>(); + Set localPhotosList = new LinkedHashSet<>(); + Set googlePhotosList = new LinkedHashSet<>(); String phoneNumber = null; String primaryTypeDisplayName = null; @@ -113,15 +111,23 @@ public void createAllGoodPriceStores(String fileName) { if (!googlePhotosList.isEmpty()) { //가장 첫 번째 사진만 실제로 다운로드까지 진행하고 나머지는 나중에 쓸 용도로 googlePhotosList에 저장 if (currentProfile.equals("dev") || currentProfile.equals("prod")) { - byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.get(0), googleApiKey); + byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.stream().findFirst().get(), googleApiKey); if (googleMapPlacesImageAsBytes != null) { String gcsPath = gcsService.uploadImage(googleMapPlacesImageAsBytes); localPhotosList.add(gcsPath); - googlePhotosList.remove(0); + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } } } else { //local이나 test 시 - localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.get(0), googleApiKey)); - googlePhotosList.remove(0); + localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.stream().findFirst().get(), googleApiKey)); + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } } } @@ -239,10 +245,10 @@ public CreateDividedGoodPriceStoresResponse createDividedGoodPriceStores(String //WKTReader Parse exception에 대한 처리를 위한 try-catch문 try { - List regularOpeningHours; - List weekdayDescriptions = new ArrayList<>(); - List localPhotosList = new ArrayList<>(); - List googlePhotosList = new ArrayList<>(); + Set regularOpeningHours; + Set weekdayDescriptions = new LinkedHashSet<>(); + Set localPhotosList = new LinkedHashSet<>(); + Set googlePhotosList = new LinkedHashSet<>(); String phoneNumber = null; String primaryTypeDisplayName = null; @@ -281,17 +287,25 @@ public CreateDividedGoodPriceStoresResponse createDividedGoodPriceStores(String } //돈이 충분히 있으면, if (currentProfile.equals("dev") || currentProfile.equals("prod")) { - byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.get(0), googleApiKey); + byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.stream().findFirst().get(), googleApiKey); if (googleMapPlacesImageAsBytes != null) { String gcsPath = gcsService.uploadImage(googleMapPlacesImageAsBytes); localPhotosList.add(gcsPath); - googlePhotosList.remove(0); + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } //소비한 비용 반영 dollars -= 0.007; } } else { //local이나 test 시 - localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.get(0), googleApiKey)); //가장 첫 번째 사진만 실제로 다운로드까지 진행하고 나머지는 나중에 쓸 용도로 googlePhotosList에 저장 - googlePhotosList.remove(0); + localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.stream().findFirst().get(), googleApiKey)); //가장 첫 번째 사진만 실제로 다운로드까지 진행하고 나머지는 나중에 쓸 용도로 googlePhotosList에 저장 + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } //소비한 비용 반영 dollars -= 0.007; } @@ -380,8 +394,8 @@ public CreateDividedGoodPriceStoresResponse createDividedGoodPriceStores(String //Google Map API에서 제공해주는 영업 시간 정보가 periods와 weekdayDescriptions 방식이 있는데, 기존에 구조화된 periods를 사용했었지만 데이터가 깨져있는 경우가 종종 있어서, //조금 더 안정적인 weekdayDescriptions으로 데이터를 받아오고 직접 파싱해서 periods 식으로 변환하여 저장하기 위함 - public List parseWeekdayDescriptions(List weekdayDescriptions) { - List storeRegularOpeningHoursList = new ArrayList<>(); + public Set parseWeekdayDescriptions(Set weekdayDescriptions) { + Set storeRegularOpeningHoursList = new LinkedHashSet<>(); for (String weekdayDescription : weekdayDescriptions) { weekdayDescription = weekdayDescription.replace(",", " "); //,는 제거 diff --git a/src/main/java/com/nainga/nainga/domain/store/application/MobeomGoogleMapStoreService.java b/src/main/java/com/nainga/nainga/domain/store/application/MobeomGoogleMapStoreService.java index 11bee79d..f82194c0 100644 --- a/src/main/java/com/nainga/nainga/domain/store/application/MobeomGoogleMapStoreService.java +++ b/src/main/java/com/nainga/nainga/domain/store/application/MobeomGoogleMapStoreService.java @@ -24,9 +24,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.util.*; import static com.nainga.nainga.domain.store.application.GoogleMapMethods.*; @@ -79,10 +77,10 @@ public void createAllMobeomStores(String fileName) { //WKTReader Parse exception에 대한 처리를 위한 try-catch문 try { - List regularOpeningHours; - List weekdayDescriptions = new ArrayList<>(); - List localPhotosList = new ArrayList<>(); - List googlePhotosList = new ArrayList<>(); + Set regularOpeningHours; + Set weekdayDescriptions = new LinkedHashSet<>(); + Set localPhotosList = new LinkedHashSet<>(); + Set googlePhotosList = new LinkedHashSet<>(); String phoneNumber = null; String primaryTypeDisplayName = null; @@ -114,15 +112,23 @@ public void createAllMobeomStores(String fileName) { if (!googlePhotosList.isEmpty()) { //가장 첫 번째 사진만 실제로 다운로드까지 진행하고 나머지는 나중에 쓸 용도로 googlePhotosList에 저장 if (currentProfile.equals("dev") || currentProfile.equals("prod")) { - byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.get(0), googleApiKey); + byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.stream().findFirst().get(), googleApiKey); if (googleMapPlacesImageAsBytes != null) { String gcsPath = gcsService.uploadImage(googleMapPlacesImageAsBytes); localPhotosList.add(gcsPath); - googlePhotosList.remove(0); + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } } } else { //local이나 test 시 - localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.get(0), googleApiKey)); - googlePhotosList.remove(0); + localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.stream().findFirst().get(), googleApiKey)); + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } } } @@ -240,10 +246,10 @@ public CreateDividedMobeomStoresResponse createDividedMobeomStores(String fileNa //WKTReader Parse exception에 대한 처리를 위한 try-catch문 try { - List regularOpeningHours; - List weekdayDescriptions = new ArrayList<>(); - List localPhotosList = new ArrayList<>(); - List googlePhotosList = new ArrayList<>(); + Set regularOpeningHours; + Set weekdayDescriptions = new LinkedHashSet<>(); + Set localPhotosList = new LinkedHashSet<>(); + Set googlePhotosList = new LinkedHashSet<>(); String phoneNumber = null; String primaryTypeDisplayName = null; @@ -282,17 +288,25 @@ public CreateDividedMobeomStoresResponse createDividedMobeomStores(String fileNa } //돈이 충분히 있으면, if (currentProfile.equals("dev") || currentProfile.equals("prod")) { - byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.get(0), googleApiKey); + byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.stream().findFirst().get(), googleApiKey); if (googleMapPlacesImageAsBytes != null) { String gcsPath = gcsService.uploadImage(googleMapPlacesImageAsBytes); localPhotosList.add(gcsPath); - googlePhotosList.remove(0); + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } //소비한 비용 반영 dollars -= 0.007; } } else { //local이나 test 시 - localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.get(0), googleApiKey)); //가장 첫 번째 사진만 실제로 다운로드까지 진행하고 나머지는 나중에 쓸 용도로 googlePhotosList에 저장 - googlePhotosList.remove(0); + localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.stream().findFirst().get(), googleApiKey)); //가장 첫 번째 사진만 실제로 다운로드까지 진행하고 나머지는 나중에 쓸 용도로 googlePhotosList에 저장 + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } //소비한 비용 반영 dollars -= 0.007; } @@ -381,8 +395,8 @@ public CreateDividedMobeomStoresResponse createDividedMobeomStores(String fileNa //Google Map API에서 제공해주는 영업 시간 정보가 periods와 weekdayDescriptions 방식이 있는데, 기존에 구조화된 periods를 사용했었지만 데이터가 깨져있는 경우가 종종 있어서, //조금 더 안정적인 weekdayDescriptions으로 데이터를 받아오고 직접 파싱해서 periods 식으로 변환하여 저장하기 위함 - public List parseWeekdayDescriptions(List weekdayDescriptions) { - List storeRegularOpeningHoursList = new ArrayList<>(); + public Set parseWeekdayDescriptions(Set weekdayDescriptions) { + Set storeRegularOpeningHoursList = new LinkedHashSet<>(); for (String weekdayDescription : weekdayDescriptions) { weekdayDescription = weekdayDescription.replace(",", " "); //,는 제거 diff --git a/src/main/java/com/nainga/nainga/domain/store/application/SafeGoogleMapStoreService.java b/src/main/java/com/nainga/nainga/domain/store/application/SafeGoogleMapStoreService.java index cb4012fb..b635b01f 100644 --- a/src/main/java/com/nainga/nainga/domain/store/application/SafeGoogleMapStoreService.java +++ b/src/main/java/com/nainga/nainga/domain/store/application/SafeGoogleMapStoreService.java @@ -24,9 +24,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.util.*; import static com.nainga.nainga.domain.store.application.GoogleMapMethods.*; @@ -78,10 +76,10 @@ public void createAllSafeStores(String fileName) { //WKTReader Parse exception에 대한 처리를 위한 try-catch문 try { - List regularOpeningHours; - List weekdayDescriptions = new ArrayList<>(); - List localPhotosList = new ArrayList<>(); - List googlePhotosList = new ArrayList<>(); + Set regularOpeningHours; + Set weekdayDescriptions = new LinkedHashSet<>(); + Set localPhotosList = new LinkedHashSet<>(); + Set googlePhotosList = new LinkedHashSet<>(); String phoneNumber = null; String primaryTypeDisplayName = null; @@ -113,15 +111,23 @@ public void createAllSafeStores(String fileName) { if (!googlePhotosList.isEmpty()) { //가장 첫 번째 사진만 실제로 다운로드까지 진행하고 나머지는 나중에 쓸 용도로 googlePhotosList에 저장 if (currentProfile.equals("dev") || currentProfile.equals("prod")) { - byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.get(0), googleApiKey); + byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.stream().findFirst().get(), googleApiKey); if (googleMapPlacesImageAsBytes != null) { String gcsPath = gcsService.uploadImage(googleMapPlacesImageAsBytes); localPhotosList.add(gcsPath); - googlePhotosList.remove(0); + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } } } else { //local이나 test 시 - localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.get(0), googleApiKey)); - googlePhotosList.remove(0); + localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.stream().findFirst().get(), googleApiKey)); + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } } } @@ -239,10 +245,10 @@ public CreateDividedSafeStoresResponse createDividedSafeStores(String fileName, //WKTReader Parse exception에 대한 처리를 위한 try-catch문 try { - List regularOpeningHours; - List weekdayDescriptions = new ArrayList<>(); - List localPhotosList = new ArrayList<>(); - List googlePhotosList = new ArrayList<>(); + Set regularOpeningHours; + Set weekdayDescriptions = new LinkedHashSet<>(); + Set localPhotosList = new LinkedHashSet<>(); + Set googlePhotosList = new LinkedHashSet<>(); String phoneNumber = null; String primaryTypeDisplayName = null; @@ -281,17 +287,25 @@ public CreateDividedSafeStoresResponse createDividedSafeStores(String fileName, } //돈이 충분히 있으면, if (currentProfile.equals("dev") || currentProfile.equals("prod")) { - byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.get(0), googleApiKey); + byte[] googleMapPlacesImageAsBytes = getGoogleMapPlacesImageAsBytes(googlePhotosList.stream().findFirst().get(), googleApiKey); if (googleMapPlacesImageAsBytes != null) { String gcsPath = gcsService.uploadImage(googleMapPlacesImageAsBytes); localPhotosList.add(gcsPath); - googlePhotosList.remove(0); + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } //소비한 비용 반영 dollars -= 0.007; } } else { //local이나 test 시 - localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.get(0), googleApiKey)); //가장 첫 번째 사진만 실제로 다운로드까지 진행하고 나머지는 나중에 쓸 용도로 googlePhotosList에 저장 - googlePhotosList.remove(0); + localPhotosList.add(getGoogleMapPlacesImageToLocal(googlePhotosList.stream().findFirst().get(), googleApiKey)); //가장 첫 번째 사진만 실제로 다운로드까지 진행하고 나머지는 나중에 쓸 용도로 googlePhotosList에 저장 + Iterator iterator = googlePhotosList.iterator(); + if (iterator.hasNext()) { //googlePhotosList에서 가장 첫 번째 원소를 제거 + iterator.next(); + iterator.remove(); + } //소비한 비용 반영 dollars -= 0.007; } @@ -380,8 +394,8 @@ public CreateDividedSafeStoresResponse createDividedSafeStores(String fileName, //Google Map API에서 제공해주는 영업 시간 정보가 periods와 weekdayDescriptions 방식이 있는데, 기존에 구조화된 periods를 사용했었지만 데이터가 깨져있는 경우가 종종 있어서, //조금 더 안정적인 weekdayDescriptions으로 데이터를 받아오고 직접 파싱해서 periods 식으로 변환하여 저장하기 위함 - public List parseWeekdayDescriptions(List weekdayDescriptions) { - List storeRegularOpeningHoursList = new ArrayList<>(); + public Set parseWeekdayDescriptions(Set weekdayDescriptions) { + Set storeRegularOpeningHoursList = new LinkedHashSet<>(); for (String weekdayDescription : weekdayDescriptions) { weekdayDescription = weekdayDescription.replace(",", " "); //,는 제거 diff --git a/src/main/java/com/nainga/nainga/domain/store/domain/Store.java b/src/main/java/com/nainga/nainga/domain/store/domain/Store.java index a1a50f5a..b82ac01f 100644 --- a/src/main/java/com/nainga/nainga/domain/store/domain/Store.java +++ b/src/main/java/com/nainga/nainga/domain/store/domain/Store.java @@ -5,6 +5,7 @@ import org.locationtech.jts.geom.Point; import java.util.List; +import java.util.Set; @Entity @Getter @@ -26,11 +27,11 @@ public class Store { @Column(columnDefinition = "GEOMETRY") private Point location; //(경도, 위도) 좌표 @ElementCollection - private List regularOpeningHours; //영업 시간 + private Set regularOpeningHours; //영업 시간 @ElementCollection - private List weekdayDescriptions; //String 형식의 영업 시간 + private Set weekdayDescriptions; //String 형식의 영업 시간 @ElementCollection - private List localPhotos; //자체 DB에 저장된 가게 사진들 + private Set localPhotos; //자체 DB에 저장된 가게 사진들 @ElementCollection - private List googlePhotos; //나중에 Google Map API에서 더 가져와야하는 사진들 + private Set googlePhotos; //나중에 Google Map API에서 더 가져와야하는 사진들 } diff --git a/src/main/java/com/nainga/nainga/domain/storecertification/dao/StoreCertificationRepository.java b/src/main/java/com/nainga/nainga/domain/storecertification/dao/StoreCertificationRepository.java index 5f8df13c..a1d05cb6 100644 --- a/src/main/java/com/nainga/nainga/domain/storecertification/dao/StoreCertificationRepository.java +++ b/src/main/java/com/nainga/nainga/domain/storecertification/dao/StoreCertificationRepository.java @@ -4,6 +4,7 @@ import com.nainga.nainga.domain.storecertification.domain.StoreCertification; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; +import jakarta.persistence.TypedQuery; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -46,7 +47,14 @@ public List findStoreCertificationsByLocation(Location north northWestLocation.getLongitude(), northWestLocation.getLatitude(), southWestLocation.getLongitude(), southWestLocation.getLatitude(), southEastLocation.getLongitude(), southEastLocation.getLatitude(), northEastLocation.getLongitude(), northEastLocation.getLatitude(), northWestLocation.getLongitude(), northWestLocation.getLatitude() ); - Query query = em.createNativeQuery("SELECT sc.* " + "FROM store_certification AS sc " + "JOIN store AS s ON sc.store_id = s.store_id " + "JOIN certification AS c ON sc.certification_id = c.certification_id " + "WHERE ST_CONTAINS(ST_POLYGONFROMTEXT(" + pointFormat + "), s.location)", StoreCertification.class); + TypedQuery query = em.createQuery( + "SELECT sc FROM StoreCertification sc " + + "JOIN FETCH sc.store s " + + "JOIN FETCH sc.certification c " + + "JOIN FETCH s.localPhotos sl " + // localPhotos를 Fetch Join + "JOIN FETCH s.regularOpeningHours sr " + // regularOpeningHours를 Fetch Join + "WHERE ST_CONTAINS(ST_POLYGONFROMTEXT(" + pointFormat + "), s.location)", + StoreCertification.class); return query.getResultList(); } diff --git a/src/main/java/com/nainga/nainga/domain/storecertification/dto/StoreCertificationsByLocationResponse.java b/src/main/java/com/nainga/nainga/domain/storecertification/dto/StoreCertificationsByLocationResponse.java index 55790f3e..16a50e29 100644 --- a/src/main/java/com/nainga/nainga/domain/storecertification/dto/StoreCertificationsByLocationResponse.java +++ b/src/main/java/com/nainga/nainga/domain/storecertification/dto/StoreCertificationsByLocationResponse.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; @Data public class StoreCertificationsByLocationResponse { @@ -16,8 +17,8 @@ public class StoreCertificationsByLocationResponse { String formattedAddress; //가게 전체 주소 String phoneNumber; //전화번호 Location location; //(경도, 위도) 좌표 - List regularOpeningHours; //영업 시간 - List localPhotos; //구글에서 실제로 다운로드 된 사진들, 현재까지는 최대 1장 + Set regularOpeningHours; //영업 시간 + Set localPhotos; //구글에서 실제로 다운로드 된 사진들, 현재까지는 최대 1장 List certificationName; //가지고 있는 인증제 이름 리스트 public StoreCertificationsByLocationResponse(StoreCertification storeCertification) {