From 9f31f661fc260badd2f011cfc75ac6b099e3f3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Fri, 6 Mar 2026 22:12:54 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EC=9B=90=EB=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/inference/utils/GeoJsonValidator.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/common/inference/utils/GeoJsonValidator.java b/src/main/java/com/kamco/cd/kamcoback/common/inference/utils/GeoJsonValidator.java index e57d9b8a..b1bdddcd 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/inference/utils/GeoJsonValidator.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/inference/utils/GeoJsonValidator.java @@ -151,7 +151,7 @@ public class GeoJsonValidator { Set foundUnique = new HashSet<>(); // 중복된 scene_id 목록 (샘플 로그 출력용이라 순서 유지 가능한 LinkedHashSet 사용) - // Set duplicates = new LinkedHashSet<>(); + Set duplicates = new LinkedHashSet<>(); // scene_id가 null 또는 blank인 feature의 개수 (데이터 이상) int nullIdCount = 0; @@ -186,9 +186,9 @@ public class GeoJsonValidator { foundUnique.add(sceneId); // foundUnique.add(sceneId)가 false면 "이미 같은 값이 있었다"는 뜻 => 중복 - // if (!foundUnique.add(sceneId)) { - // duplicates.add(sceneId); - // } + if (!foundUnique.add(sceneId)) { + duplicates.add(sceneId); + } } // ========================================================= @@ -232,7 +232,7 @@ public class GeoJsonValidator { requested.size(), // 요청 도엽 유니크 수 foundUnique.size(), // GeoJSON에서 발견된 scene_id 유니크 수 nullIdCount, // scene_id가 비어있는 feature 수 - 0, // 중복 scene_id 종류 수 + duplicates.size(), // 중복 scene_id 종류 수 missing.size(), // 요청했지만 빠진 도엽 수 extra.size()); // 요청하지 않았는데 들어온 도엽 수 @@ -261,12 +261,12 @@ public class GeoJsonValidator { // - 요청 문법은 맞지만(파일은 있고 JSON도 읽힘), // 내용(정합성)이 요구사항을 만족하지 못하는 경우에 적합. // ========================================================= - if (!missing.isEmpty() || !extra.isEmpty() || nullIdCount > 0) { + if (!missing.isEmpty() || !extra.isEmpty() || !duplicates.isEmpty() || nullIdCount > 0) { throw new ResponseStatusException( HttpStatus.UNPROCESSABLE_ENTITY, String.format( "GeoJSON validation failed: missing=%d, extra=%d, duplicates=%d, nullId=%d", - missing.size(), extra.size(), 0, nullIdCount)); + missing.size(), extra.size(), duplicates.size(), nullIdCount)); } // 모든 조건을 통과하면 정상 From 3752b832920a3f17afcc5c56af76a823e1445781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Sat, 7 Mar 2026 00:56:51 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EC=9D=B8=ED=8D=BC=EB=9F=B0=EC=8A=A4?= =?UTF-8?q?=EC=8B=A4=ED=96=89=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inference/dto/InferenceResultDto.java | 2 +- .../service/InferenceResultService.java | 112 +++++++++--------- .../core/InferenceResultCoreService.java | 6 +- .../postgres/core/MapSheetMngCoreService.java | 11 +- .../postgres/entity/MapSheetMngHstEntity.java | 13 +- .../mapsheet/MapSheetMngRepositoryCustom.java | 9 +- .../mapsheet/MapSheetMngRepositoryImpl.java | 72 ++++++----- .../MapSheetMngYearRepositoryImpl.java | 26 +++- 8 files changed, 130 insertions(+), 121 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultDto.java b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultDto.java index 6a0f5b55..5e765fc7 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultDto.java @@ -278,7 +278,7 @@ public class InferenceResultDto { @EnumValid( enumClass = DetectOption.class, message = "탐지 데이터 옵션은 '추론제외', '이전 년도 도엽 사용' 만 사용 가능합니다.") - private String detectOption; + private DetectOption detectOption; @Schema(description = "5k 도협 번호 목록", example = "[33605,33606, 33610, 34802, 35603, 35611]") @NotNull diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java index 88f61b4e..17455cdf 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java @@ -56,7 +56,7 @@ import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; -import lombok.extern.log4j.Log4j2; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.http.HttpHeaders; @@ -68,7 +68,7 @@ import org.springframework.transaction.annotation.Transactional; /** 추론 관리 */ @Service -@Log4j2 +@Slf4j @RequiredArgsConstructor @Transactional(readOnly = true) public class InferenceResultService { @@ -129,47 +129,39 @@ public class InferenceResultService { @Transactional public UUID run(InferenceResultDto.RegReq req) { log.info("inference start request = {}", req); - if (req.getDetectOption().equals(DetectOption.EXCL.getId())) { + DetectOption detectOption = req.getDetectOption(); + if (detectOption == DetectOption.EXCL) { // 추론 제외 일때 EXCL return runExcl(req); } - // 이전연도 도엽 사용 일때 PREV return runPrev(req); } /** - * 변화탐지 옵션 추론제외 실행 + * 변화탐지 [옵션 추론제외 실행] * * @param req * @return */ public UUID runExcl(InferenceResultDto.RegReq req) { - // TODO 쿼리로 한번에 할수 있게 수정해야하나.. // 기준연도 실행가능 도엽 조회 List targetMngList = - mapSheetMngCoreService.getMapSheetMngHst( - req.getTargetYyyy(), req.getMapSheetScope(), req.getMapSheetNum()); - - // List mngList = - // mapSheetMngCoreService.findExecutableSheets( - // req.getCompareYyyy(), - // req.getTargetYyyy(), - // req.getMapSheetScope(), - // req.getMapSheetNum()); + mapSheetMngCoreService.getMapSheetMngHst(req.getTargetYyyy(), req.getMapSheetNum()); if (targetMngList == null || targetMngList.isEmpty()) { throw new CustomApiException("NOT_FOUND_MAP_SHEET_NUM", HttpStatus.NOT_FOUND); } + log.info("targetMngList size = {}", targetMngList.size()); // 비교연도 실행가능 도엽 조회 List compareMngList = - mapSheetMngCoreService.getMapSheetMngHst( - req.getCompareYyyy(), req.getMapSheetScope(), req.getMapSheetNum()); + mapSheetMngCoreService.getMapSheetMngHst(req.getCompareYyyy(), req.getMapSheetNum()); if (compareMngList == null || compareMngList.isEmpty()) { throw new CustomApiException("NOT_FOUND_COMPARE_YEAR", HttpStatus.NOT_FOUND); } + log.info("compareMngList size = {}", compareMngList.size()); // compare 도엽번호 Set 구성 Set compareSet = @@ -211,14 +203,14 @@ public class InferenceResultService { log.info( """ - ===== MapSheet Year Comparison ===== - target Total: {} - compare Total: {} - Intersection: {} - target Only (Excluded): {} - compare Only: {} - ==================================== - """, + ===== MapSheet Year Comparison ===== + target Total: {} + compare Total: {} + Intersection: {} + target Only (Excluded): {} + compare Only: {} + ==================================== + """, targetTotal, compareTotal, intersection, @@ -269,27 +261,30 @@ public class InferenceResultService { */ @Transactional public UUID runPrev(InferenceResultDto.RegReq req) { - // TODO 쿼리로 한번에 할수 있게 수정해야하나.. - // 기준연도 실행가능 도엽 조회 - List targetMngList = - mapSheetMngCoreService.getMapSheetMngHst( - req.getTargetYyyy(), req.getMapSheetScope(), req.getMapSheetNum()); + Integer targetYyyy = req.getTargetYyyy(); + Integer compareYyyy = req.getCompareYyyy(); + String mapSheetScope = req.getMapSheetScope(); + log.info("[{}|{}}] ,{}", compareYyyy, targetYyyy, mapSheetScope); + + // 기준연도 실행가능 도엽 조회[AFTER] + List targetMngList = + mapSheetMngCoreService.getMapSheetMngHst(targetYyyy, req.getMapSheetNum()); + + log.info("targetMngList size = {}", targetMngList.size()); if (targetMngList == null || targetMngList.isEmpty()) { throw new CustomApiException("NOT_FOUND_TARGET_YEAR", HttpStatus.NOT_FOUND); } // 비교연도 실행가능 도엽 조회 List compareMngList = - mapSheetMngCoreService.getMapSheetMngHst( - req.getCompareYyyy(), req.getMapSheetScope(), req.getMapSheetNum()); + mapSheetMngCoreService.getMapSheetMngHst(compareYyyy, req.getMapSheetNum()); + log.info("compareMngList size = {}", compareMngList.size()); if (compareMngList == null || compareMngList.isEmpty()) { throw new CustomApiException("NOT_FOUND_COMPARE_YEAR", HttpStatus.NOT_FOUND); } - log.info("targetMngList size = {}", targetMngList.size()); - log.info("compareMngList size = {}", compareMngList.size()); log.info("Difference in count = {}", targetMngList.size() - compareMngList.size()); // 로그용 원본 카운트 (이전도엽 추가 전) @@ -316,7 +311,7 @@ public class InferenceResultService { // 이전연도 초회 추가 compareMngList.addAll( mapSheetMngCoreService.findFallbackCompareYearByMapSheets( - req.getCompareYyyy(), targetOnlyMapSheetNums)); + compareYyyy, targetOnlyMapSheetNums)); log.info("fallback compare size= {}", compareMngList.size()); @@ -362,15 +357,15 @@ public class InferenceResultService { log.info( """ - ===== MapSheet Year Comparison ===== - target Total: {} - compare Total(before fallback): {} - compare Total(after fallback): {} - Intersection: {} - target Only (Excluded): {} - compare Only: {} - ==================================== - """, + ===== MapSheet Year Comparison ===== + target Total: {} + compare Total(before fallback): {} + compare Total(after fallback): {} + Intersection: {} + target Only (Excluded): {} + compare Only: {} + ==================================== + """, targetTotal, compareTotalBeforeFallback, compareTotalAfterFallback, @@ -385,18 +380,12 @@ public class InferenceResultService { // compare 기준 geojson 생성 Scene compareScene = getSceneInference( - compareMngList, - req.getCompareYyyy().toString(), - req.getMapSheetScope(), - req.getDetectOption()); + compareMngList, compareYyyy.toString(), mapSheetScope, req.getDetectOption()); // target 기준 geojson 생성 Scene targetScene = getSceneInference( - req.getTargetYyyy().toString(), - mapSheetNums, - req.getMapSheetScope(), - req.getDetectOption()); + targetYyyy.toString(), mapSheetNums, mapSheetScope, req.getDetectOption()); log.info("비교년도 geojson 파일 validation ===== {}", compareScene.getFilePath()); GeoJsonValidator.validateWithRequested(compareScene.getFilePath(), mapSheetNums); @@ -672,7 +661,7 @@ public class InferenceResultService { * @return */ private Scene getSceneInference( - String yyyy, List mapSheetNums, String mapSheetScope, String detectOption) { + String yyyy, List mapSheetNums, String mapSheetScope, DetectOption detectOption) { // geojson 생성시 필요한 영상파일 정보 조회 List features = @@ -698,7 +687,7 @@ public class InferenceResultService { * @return */ private Scene getSceneInference( - List yearDtos, String yyyy, String mapSheetScope, String detectOption) { + List yearDtos, String yyyy, String mapSheetScope, DetectOption detectOption) { List features = mapSheetMngCoreService.loadSceneInferenceByFallbackYears(yearDtos); @@ -983,7 +972,10 @@ public class InferenceResultService { * @return Scene */ private Scene writeSceneGeoJson( - String yyyy, String mapSheetScope, String detectOption, List sceneInference) { + String yyyy, + String mapSheetScope, + DetectOption detectOption, + List sceneInference) { boolean isAll = MapSheetScope.ALL.getId().equals(mapSheetScope); String optionSuffix = buildOptionSuffix(detectOption); @@ -1032,9 +1024,13 @@ public class InferenceResultService { * @param detectOption * @return */ - private String buildOptionSuffix(String detectOption) { - if (DetectOption.EXCL.getId().equals(detectOption)) return "_EXCL"; - if (DetectOption.PREV.getId().equals(detectOption)) return "_PREV"; + private String buildOptionSuffix(DetectOption detectOption) { + if (DetectOption.EXCL == detectOption) { + return "_EXCL"; + } + if (DetectOption.PREV == detectOption) { + return "_PREV"; + } return ""; } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java index 159739cc..554f20ea 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java @@ -47,7 +47,7 @@ import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.Stream; import lombok.RequiredArgsConstructor; -import lombok.extern.log4j.Log4j2; +import lombok.extern.slf4j.Slf4j; import org.springframework.dao.DataAccessException; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; @@ -55,7 +55,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service -@Log4j2 +@Slf4j @RequiredArgsConstructor public class InferenceResultCoreService { @@ -120,7 +120,7 @@ public class InferenceResultCoreService { mapSheetLearnEntity.setCompareYyyy(req.getCompareYyyy()); mapSheetLearnEntity.setTargetYyyy(req.getTargetYyyy()); mapSheetLearnEntity.setMapSheetScope(req.getMapSheetScope()); - mapSheetLearnEntity.setDetectOption(req.getDetectOption()); + mapSheetLearnEntity.setDetectOption(req.getDetectOption().getId()); mapSheetLearnEntity.setCreatedUid(userUtil.getId()); mapSheetLearnEntity.setMapSheetCnt(mapSheetName); mapSheetLearnEntity.setDetectingCnt(0L); diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngCoreService.java index 4611bd30..23d81112 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngCoreService.java @@ -345,16 +345,15 @@ public class MapSheetMngCoreService { * 변화탐지 실행 가능 비교년도 조회 * * @param mngYyyy 비교년도 - * @param mapId 5k 도엽번호 + * @param mapIds 5k 도엽번호 * @return List */ - public List getByHstMapSheetCompareList(int mngYyyy, List mapId) { - return mapSheetMngYearRepository.findByHstMapSheetCompareList(mngYyyy, mapId); + public List getByHstMapSheetCompareList(int mngYyyy, List mapIds) { + return mapSheetMngYearRepository.findByHstMapSheetCompareList(mngYyyy, mapIds); } - public List getMapSheetMngHst( - Integer year, String mapSheetScope, List mapSheetNum) { - return mapSheetMngRepository.getMapSheetMngHst(year, mapSheetScope, mapSheetNum); + public List getMapSheetMngHst(Integer year, List mapSheetNums50k) { + return mapSheetMngRepository.getMapSheetMngHst(year, mapSheetNums50k); } /** diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngHstEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngHstEntity.java index 1d082990..9a5135ec 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngHstEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngHstEntity.java @@ -53,8 +53,6 @@ import lombok.NoArgsConstructor; * system leveraging 1:5k map data. */ @Getter -// entity의 접근제어를 위해 @setter를 사용 x -// @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity // 영상관리이력 @@ -92,7 +90,7 @@ public class MapSheetMngHstEntity extends CommonDateEntity { private Integer scaleRatio; @Column(name = "data_state", length = 20) - private String dataState; + private String dataState; // DONE,NOTYET 둘중하나임 같은연도는 같은값 @Column(name = "data_state_dttm") private ZonedDateTime dataStateDttm; @@ -165,13 +163,4 @@ public class MapSheetMngHstEntity extends CommonDateEntity { @Column(name = "upload_id") private String uploadId; - - // 파일정보 업데이트 - public void updateFileInfos(Long tifSizeBytes, Long tfwSizeBytes) { - tifSizeBytes = tifSizeBytes == null ? 0L : tifSizeBytes; - tfwSizeBytes = tfwSizeBytes == null ? 0L : tfwSizeBytes; - this.tifSizeBytes = tifSizeBytes; - this.tfwSizeBytes = tfwSizeBytes; - this.totalSizeBytes = tifSizeBytes + tfwSizeBytes; - } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryCustom.java index 38bdd9fc..1877b2aa 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryCustom.java @@ -141,12 +141,13 @@ public interface MapSheetMngRepositoryCustom { void insertMapSheetMngTile(@Valid AddReq addReq); /** - * 연도 조건으로 도엽번호 조회 + * 연도별 도엽 목록 조회 * - * @param year 연도 - * @return 추론 가능한 도엽 정보 + * @param year 관리연도 + * @param mapSheetNums50k 50k 도엽번호 리스트 (null 또는 empty인 경우 전체 조회) + * @return 도엽 목록 */ - List getMapSheetMngHst(Integer year, String mapSheetScope, List mapSheetNum); + List getMapSheetMngHst(Integer year, List mapSheetNums50k); /** * 비교연도 사용 가능한 이전도엽을 조회한다. diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryImpl.java index 6f51214e..41d29ba7 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryImpl.java @@ -1,5 +1,6 @@ package com.kamco.cd.kamcoback.postgres.repository.mapsheet; +import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx50kEntity.mapInkx50kEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngEntity.mapSheetMngEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngFileEntity.mapSheetMngFileEntity; @@ -10,12 +11,12 @@ import static com.querydsl.core.types.dsl.Expressions.nullExpression; import com.kamco.cd.kamcoback.common.enums.CommonUseStatus; import com.kamco.cd.kamcoback.common.geometry.GeoJsonFileWriter.ImageFeature; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheetScope; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.AddReq; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngListDto; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.YearSearchReq; import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity; +import com.kamco.cd.kamcoback.postgres.entity.QMapInkx50kEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngFileEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngHstEntity; @@ -27,7 +28,6 @@ import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.CaseBuilder; import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.NumberExpression; -import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; @@ -50,7 +50,6 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport implements MapSheetMngRepositoryCustom { private final JPAQueryFactory queryFactory; - private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)"); @PersistenceContext private EntityManager em; @@ -1084,11 +1083,27 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport mapSheetMngHstEntity.mapSheetNum)); } + /** + * 영상데이터관리 > 연도별 도엽 목록 조회 + * + * @param year 관리연도 + * @param mapSheetNums50k 50k 도엽번호 리스트 (null 또는 empty인 경우 전체 조회) + * @return 도엽 목록 + */ @Override - public List getMapSheetMngHst( - Integer year, String mapSheetScope, List mapSheetNum) { + public List getMapSheetMngHst(Integer year, List mapSheetNums50k) { + /* + 검색조건: + - ✅ 데이터 처리 완료(data_state='DONE') + - ✅ 동기화 완료(sync_state='DONE' OR sync_check_state='DONE') + - ✅ 추론 사용(use_inference='USE') + - ✅ 지정 연도(mng_yyyy=year) + - ✅ 완료된 TIF 파일 존재 + - ✅ 사용 중인 도엽만(mapInkx5k.useInference='USE') + - ✅ 50k 도엽번호로 필터링 (mapSheetNums50k가 있는 경우) + */ BooleanBuilder whereBuilder = new BooleanBuilder(); - + whereBuilder.and(mapSheetMngHstEntity.mngYyyy.eq(year)); whereBuilder.and(mapSheetMngHstEntity.dataState.eq("DONE")); whereBuilder.and( mapSheetMngHstEntity @@ -1097,40 +1112,19 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport .or(mapSheetMngHstEntity.syncCheckState.eq("DONE"))); whereBuilder.and(mapSheetMngHstEntity.useInference.eq("USE")); - whereBuilder.and(mapSheetMngHstEntity.mngYyyy.eq(year)); - + // TIF 파일 존재 여부 확인 whereBuilder.and( JPAExpressions.selectOne() .from(mapSheetMngFileEntity) .where( mapSheetMngFileEntity .hstUid - .eq(mapSheetMngHstEntity.hstUid) // FK 관계에 맞게 유지 + .eq(mapSheetMngHstEntity.hstUid) .and(mapSheetMngFileEntity.fileExt.eq("tif")) .and(mapSheetMngFileEntity.fileState.eq("DONE")) .and(mapSheetMngFileEntity.fileDel.eq(false))) .exists()); - BooleanBuilder likeBuilder = new BooleanBuilder(); - - if (MapSheetScope.PART.getId().equals(mapSheetScope)) { - List list = mapSheetNum; - if (list == null || list.isEmpty()) { - return List.of(); - } - - for (String prefix : list) { - if (prefix == null || prefix.isBlank()) { - continue; - } - likeBuilder.or(mapSheetMngHstEntity.mapSheetNum.like(prefix.trim() + "%")); - } - } - - if (likeBuilder.hasValue()) { - whereBuilder.and(likeBuilder); - } - return queryFactory .select( Projections.constructor( @@ -1147,7 +1141,8 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport .mapidcdNo .eq(mapSheetMngHstEntity.mapSheetNum) .and(mapInkx5kEntity.useInference.eq(CommonUseStatus.USE))) - .where(whereBuilder) + .innerJoin(mapInkx5kEntity.mapInkx50k, mapInkx50kEntity) + .where(whereBuilder, inScenes50(mapInkx50kEntity, mapSheetNums50k)) .fetch(); } @@ -1179,7 +1174,11 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport h.syncState.eq("DONE").or(h.syncCheckState.eq("DONE")), JPAExpressions.selectOne() .from(f) - .where(f.hstUid.eq(h.hstUid), f.fileExt.eq("tif"), f.fileState.eq("DONE")) + .where( + f.hstUid.eq(h.hstUid), + f.fileExt.eq("tif"), + f.fileState.eq("DONE"), + f.fileDel.eq(false)) .exists(), // mapSheetNum별 최대 mngYyyy인 행만 남김 @@ -1197,8 +1196,17 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport .where( f2.hstUid.eq(h2.hstUid), f2.fileExt.eq("tif"), - f2.fileState.eq("DONE")) + f2.fileState.eq("DONE"), + f2.fileDel.eq(false)) .exists()))) .fetch(); } + + // 도엽번호(1:50k) IN 쿼리조건 + private BooleanExpression inScenes50(QMapInkx50kEntity mapInkx50k, List sceneIds) { + if (sceneIds == null || sceneIds.isEmpty()) { + return null; + } + return mapInkx50k.mapidcdNo.in(sceneIds); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngYearRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngYearRepositoryImpl.java index fd56b310..349ce416 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngYearRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngYearRepositoryImpl.java @@ -88,17 +88,33 @@ public class MapSheetMngYearRepositoryImpl implements MapSheetMngYearRepositoryC */ @Override public List findByHstMapSheetCompareList(int mngYyyy, List mapIds) { - QMapSheetMngYearYnEntity y = QMapSheetMngYearYnEntity.mapSheetMngYearYnEntity; + QMapSheetMngYearYnEntity mapSheetMngYearYn = QMapSheetMngYearYnEntity.mapSheetMngYearYnEntity; + + // SELECT + // concat(?, '') as col_0_0_, -- 파라미터 mngYyyy (문자열) + // m.map_sheet_num as col_1_0_, -- 도엽번호 + // MAX(m.mng_yyyy) as col_2_0_ -- 최대 관리연도 + // FROM tb_map_sheet_mng_year_yn m + // WHERE m.map_sheet_num IN (?, ?, ..., ?) -- mapIds 리스트 + // AND m.yn = 'Y' -- 파일 존재 여부 + // AND m.mng_yyyy <= ? -- 기준연도 이하만 + // GROUP BY m.map_sheet_num StringExpression mngYyyyStr = Expressions.stringTemplate("concat({0}, '')", mngYyyy); return queryFactory .select( Projections.constructor( - MngListCompareDto.class, mngYyyyStr, y.id.mapSheetNum, y.id.mngYyyy.max())) - .from(y) - .where(y.id.mapSheetNum.in(mapIds), y.yn.eq("Y"), y.id.mngYyyy.loe(mngYyyy)) - .groupBy(y.id.mapSheetNum) + MngListCompareDto.class, + mngYyyyStr, + mapSheetMngYearYn.id.mapSheetNum, + mapSheetMngYearYn.id.mngYyyy.max())) + .from(mapSheetMngYearYn) + .where( + mapSheetMngYearYn.id.mapSheetNum.in(mapIds), + mapSheetMngYearYn.yn.eq("Y"), + mapSheetMngYearYn.id.mngYyyy.loe(mngYyyy)) + .groupBy(mapSheetMngYearYn.id.mapSheetNum) .fetch(); }