파일생성 추가
This commit is contained in:
@@ -6,7 +6,7 @@ import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheet;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapInkx5kEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataGeomEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.repository.Inference.InferenceResultRepository;
|
||||
import com.kamco.cd.kamcoback.postgres.repository.Inference.MapSheetAnalDataRepository;
|
||||
import com.kamco.cd.kamcoback.postgres.repository.scene.MapInkx5kRepository;
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@@ -20,7 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
@RequiredArgsConstructor
|
||||
public class InferenceResultCoreService {
|
||||
|
||||
private final InferenceResultRepository inferenceResultRepository;
|
||||
private final MapSheetAnalDataRepository mapSheetAnalDataRepository;
|
||||
private final MapInkx5kRepository mapInkx5kRepository;
|
||||
|
||||
/**
|
||||
@@ -31,7 +31,7 @@ public class InferenceResultCoreService {
|
||||
*/
|
||||
public Page<InferenceResultDto.AnalResList> getInferenceResultList(
|
||||
InferenceResultDto.SearchReq searchReq) {
|
||||
return inferenceResultRepository.getInferenceResultList(searchReq);
|
||||
return mapSheetAnalDataRepository.getInferenceResultList(searchReq);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ public class InferenceResultCoreService {
|
||||
*/
|
||||
public InferenceResultDto.AnalResSummary getInferenceResultSummary(Long id) {
|
||||
InferenceResultDto.AnalResSummary summary =
|
||||
inferenceResultRepository
|
||||
mapSheetAnalDataRepository
|
||||
.getInferenceResultSummary(id)
|
||||
.orElseThrow(() -> new EntityNotFoundException("요약정보를 찾을 수 없습니다. " + id));
|
||||
return summary;
|
||||
@@ -55,7 +55,7 @@ public class InferenceResultCoreService {
|
||||
* @return
|
||||
*/
|
||||
public List<Dashboard> getDashboard(Long id) {
|
||||
return inferenceResultRepository.getDashboard(id);
|
||||
return mapSheetAnalDataRepository.getDashboard(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ public class InferenceResultCoreService {
|
||||
*/
|
||||
public Page<InferenceResultDto.Geom> getInferenceResultGeomList(
|
||||
Long id, InferenceResultDto.SearchGeoReq searchGeoReq) {
|
||||
return inferenceResultRepository.getInferenceGeomList(id, searchGeoReq);
|
||||
return mapSheetAnalDataRepository.getInferenceGeomList(id, searchGeoReq);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,13 +80,13 @@ public class InferenceResultCoreService {
|
||||
@NotNull Long analyId, InferenceResultDto.SearchGeoReq searchReq) {
|
||||
// 분석 ID 에 해당하는 dataids를 가져온다.
|
||||
List<Long> dataIds =
|
||||
inferenceResultRepository.listAnalyGeom(analyId).stream()
|
||||
mapSheetAnalDataRepository.listAnalyGeom(analyId).stream()
|
||||
.mapToLong(MapSheetAnalDataEntity::getId)
|
||||
.boxed()
|
||||
.toList();
|
||||
// 해당데이터의 폴리곤데이터를 가져온다
|
||||
Page<MapSheetAnalDataGeomEntity> mapSheetAnalDataGeomEntities =
|
||||
inferenceResultRepository.listInferenceResultWithGeom(dataIds, searchReq);
|
||||
mapSheetAnalDataRepository.listInferenceResultWithGeom(dataIds, searchReq);
|
||||
return mapSheetAnalDataGeomEntities.map(MapSheetAnalDataGeomEntity::toEntity);
|
||||
}
|
||||
|
||||
@@ -97,13 +97,13 @@ public class InferenceResultCoreService {
|
||||
* @return
|
||||
*/
|
||||
public List<Long> getSheets(Long id) {
|
||||
return inferenceResultRepository.getSheets(id);
|
||||
return mapSheetAnalDataRepository.getSheets(id);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<MapSheet> listGetScenes5k(Long analyId) {
|
||||
List<String> sceneCodes =
|
||||
inferenceResultRepository.listAnalyGeom(analyId).stream()
|
||||
mapSheetAnalDataRepository.listAnalyGeom(analyId).stream()
|
||||
.mapToLong(MapSheetAnalDataEntity::getMapSheetNum)
|
||||
.mapToObj(String::valueOf)
|
||||
.toList();
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.kamco.cd.kamcoback.postgres.core;
|
||||
|
||||
import com.kamco.cd.kamcoback.postgres.entity.InferenceResultEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.repository.Inference.InferenceResultRepository;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.hibernate.ScrollableResults;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class InferenceResultShpCoreService {
|
||||
|
||||
private final InferenceResultRepository inferenceResultRepository;
|
||||
|
||||
public record ShpKey(Integer stage, Long mapId, Integer input1, Integer input2) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* DB를 스트리밍하면서 그룹이 완성될 때마다 handler로 넘김 handler: (key, groupRows)
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public void streamGrouped(int fetchSize, BiConsumer<ShpKey, List<InferenceResultEntity>> handler) {
|
||||
|
||||
ScrollableResults cursor = inferenceResultRepository.scrollAllOrdered(fetchSize);
|
||||
|
||||
ShpKey currentKey = null;
|
||||
List<InferenceResultEntity> buffer = new ArrayList<>(2000);
|
||||
|
||||
try {
|
||||
while (cursor.next()) {
|
||||
InferenceResultEntity row = (InferenceResultEntity) cursor.get();
|
||||
|
||||
ShpKey key = new ShpKey(row.getStage(), row.getMapId(), row.getInput1(), row.getInput2());
|
||||
|
||||
// 키 변경 -> 이전 그룹 완료
|
||||
if (currentKey != null && !currentKey.equals(key)) {
|
||||
handler.accept(currentKey, buffer);
|
||||
buffer = new ArrayList<>(2000);
|
||||
}
|
||||
|
||||
currentKey = key;
|
||||
buffer.add(row);
|
||||
}
|
||||
|
||||
// 마지막 그룹
|
||||
if (currentKey != null && !buffer.isEmpty()) {
|
||||
handler.accept(currentKey, buffer);
|
||||
}
|
||||
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.kamco.cd.kamcoback.postgres.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "inference_results")
|
||||
public class InferenceResultEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "uid", nullable = false)
|
||||
private Long id;
|
||||
|
||||
@NotNull
|
||||
@ColumnDefault("uuid_generate_v4()")
|
||||
@Column(name = "uuid", nullable = false)
|
||||
private UUID uuid;
|
||||
|
||||
@Column(name = "stage")
|
||||
private Integer stage;
|
||||
|
||||
@Column(name = "cd_prob")
|
||||
private Float cdProb;
|
||||
|
||||
@Column(name = "input1")
|
||||
private Integer input1;
|
||||
|
||||
@Column(name = "input2")
|
||||
private Integer input2;
|
||||
|
||||
@Column(name = "map_id")
|
||||
private Long mapId;
|
||||
|
||||
@Size(max = 20)
|
||||
@Column(name = "before_class", length = 20)
|
||||
private String beforeClass;
|
||||
|
||||
@Column(name = "before_probability")
|
||||
private Float beforeProbability;
|
||||
|
||||
@Size(max = 20)
|
||||
@Column(name = "after_class", length = 20)
|
||||
private String afterClass;
|
||||
|
||||
@Column(name = "after_probability")
|
||||
private Float afterProbability;
|
||||
|
||||
@ColumnDefault("st_area(geometry)")
|
||||
@Column(name = "area")
|
||||
private Float area;
|
||||
|
||||
@NotNull
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "created_dttm", nullable = false)
|
||||
private ZonedDateTime createdDttm;
|
||||
|
||||
@NotNull
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "updated_dttm", nullable = false)
|
||||
private ZonedDateTime updatedDttm;
|
||||
|
||||
@Column(name = "geometry", columnDefinition = "geometry not null")
|
||||
private Geometry geometry;
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.kamco.cd.kamcoback.postgres.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.time.ZonedDateTime;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "tb_map_sheet_anal_data_inference")
|
||||
public class MapSheetAnalDataInferenceEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "data_uid", nullable = false)
|
||||
private Long id;
|
||||
|
||||
@Size(max = 128)
|
||||
@Column(name = "data_name", length = 128)
|
||||
private String dataName;
|
||||
|
||||
@Size(max = 255)
|
||||
@Column(name = "data_path")
|
||||
private String dataPath;
|
||||
|
||||
@Size(max = 128)
|
||||
@Column(name = "data_type", length = 128)
|
||||
private String dataType;
|
||||
|
||||
@Size(max = 128)
|
||||
@Column(name = "data_crs_type", length = 128)
|
||||
private String dataCrsType;
|
||||
|
||||
@Size(max = 255)
|
||||
@Column(name = "data_crs_type_name")
|
||||
private String dataCrsTypeName;
|
||||
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "created_dttm")
|
||||
private ZonedDateTime createdDttm;
|
||||
|
||||
@Column(name = "created_uid")
|
||||
private Long createdUid;
|
||||
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "updated_dttm")
|
||||
private ZonedDateTime updatedDttm;
|
||||
|
||||
@Column(name = "updated_uid")
|
||||
private Long updatedUid;
|
||||
|
||||
@Column(name = "compare_yyyy")
|
||||
private Integer compareYyyy;
|
||||
|
||||
@Column(name = "target_yyyy")
|
||||
private Integer targetYyyy;
|
||||
|
||||
@Column(name = "data_json", length = Integer.MAX_VALUE)
|
||||
private String dataJson;
|
||||
|
||||
@Size(max = 20)
|
||||
@ColumnDefault("'0'")
|
||||
@Column(name = "data_state", length = 20)
|
||||
private String dataState;
|
||||
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "data_state_dttm")
|
||||
private ZonedDateTime dataStateDttm;
|
||||
|
||||
@Column(name = "anal_strt_dttm")
|
||||
private ZonedDateTime analStrtDttm;
|
||||
|
||||
@Column(name = "anal_end_dttm")
|
||||
private ZonedDateTime analEndDttm;
|
||||
|
||||
@ColumnDefault("0")
|
||||
@Column(name = "anal_sec")
|
||||
private Long analSec;
|
||||
|
||||
@Size(max = 20)
|
||||
@Column(name = "anal_state", length = 20)
|
||||
private String analState;
|
||||
|
||||
@Column(name = "anal_uid")
|
||||
private Long analUid;
|
||||
|
||||
@Column(name = "map_sheet_num")
|
||||
private Long mapSheetNum;
|
||||
|
||||
@ColumnDefault("0")
|
||||
@Column(name = "detecting_cnt")
|
||||
private Long detectingCnt;
|
||||
|
||||
@ColumnDefault("0")
|
||||
@Column(name = "pnu")
|
||||
private Long pnu;
|
||||
|
||||
@Size(max = 20)
|
||||
@Column(name = "down_state", length = 20)
|
||||
private String downState;
|
||||
|
||||
@Column(name = "down_state_dttm")
|
||||
private ZonedDateTime downStateDttm;
|
||||
|
||||
@Size(max = 20)
|
||||
@Column(name = "fit_state", length = 20)
|
||||
private String fitState;
|
||||
|
||||
@Column(name = "fit_state_dttm")
|
||||
private ZonedDateTime fitStateDttm;
|
||||
|
||||
@Column(name = "labeler_uid")
|
||||
private Long labelerUid;
|
||||
|
||||
@Size(max = 20)
|
||||
@ColumnDefault("NULL")
|
||||
@Column(name = "label_state", length = 20)
|
||||
private String labelState;
|
||||
|
||||
@Column(name = "label_state_dttm")
|
||||
private ZonedDateTime labelStateDttm;
|
||||
|
||||
@Column(name = "tester_uid")
|
||||
private Long testerUid;
|
||||
|
||||
@Size(max = 20)
|
||||
@Column(name = "test_state", length = 20)
|
||||
private String testState;
|
||||
|
||||
@Column(name = "test_state_dttm")
|
||||
private ZonedDateTime testStateDttm;
|
||||
|
||||
@Column(name = "fit_state_cmmnt", length = Integer.MAX_VALUE)
|
||||
private String fitStateCmmnt;
|
||||
|
||||
@Column(name = "ref_map_sheet_num")
|
||||
private Long refMapSheetNum;
|
||||
|
||||
@Column(name = "stage")
|
||||
private Integer stage;
|
||||
|
||||
@Column(name = "file_created_yn")
|
||||
private Boolean fileCreatedYn;
|
||||
|
||||
@Size(max = 100)
|
||||
@Column(name = "m1", length = 100)
|
||||
private String m1;
|
||||
|
||||
@Size(max = 100)
|
||||
@Column(name = "m2", length = 100)
|
||||
private String m2;
|
||||
|
||||
@Size(max = 100)
|
||||
@Column(name = "m3", length = 100)
|
||||
private String m3;
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package com.kamco.cd.kamcoback.postgres.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "tb_map_sheet_anal_data_inference_geom")
|
||||
public class MapSheetAnalDataInferenceGeomEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "geo_uid")
|
||||
private Long geoUid;
|
||||
|
||||
@Column(name = "cd_prob")
|
||||
private Float cdProb;
|
||||
|
||||
@Size(max = 40)
|
||||
@Column(name = "class_before_cd", length = 40)
|
||||
private String classBeforeCd;
|
||||
|
||||
@Column(name = "class_before_prob")
|
||||
private Float classBeforeProb;
|
||||
|
||||
@Size(max = 40)
|
||||
@Column(name = "class_after_cd", length = 40)
|
||||
private String classAfterCd;
|
||||
|
||||
@Column(name = "class_after_prob")
|
||||
private Float classAfterProb;
|
||||
|
||||
@Column(name = "map_sheet_num")
|
||||
private Long mapSheetNum;
|
||||
|
||||
@Column(name = "compare_yyyy")
|
||||
private Integer compareYyyy;
|
||||
|
||||
@Column(name = "target_yyyy")
|
||||
private Integer targetYyyy;
|
||||
|
||||
@Column(name = "area")
|
||||
private Float area;
|
||||
|
||||
@Size(max = 100)
|
||||
@Column(name = "geo_type", length = 100)
|
||||
private String geoType;
|
||||
|
||||
@Column(name = "data_uid")
|
||||
private Long dataUid;
|
||||
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "created_dttm")
|
||||
private OffsetDateTime createdDttm;
|
||||
|
||||
@Column(name = "created_uid")
|
||||
private Long createdUid;
|
||||
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "updated_dttm")
|
||||
private OffsetDateTime updatedDttm;
|
||||
|
||||
@Column(name = "updated_uid")
|
||||
private Long updatedUid;
|
||||
|
||||
@ColumnDefault("0")
|
||||
@Column(name = "geom_cnt")
|
||||
private Long geomCnt;
|
||||
|
||||
@ColumnDefault("0")
|
||||
@Column(name = "pnu")
|
||||
private Long pnu;
|
||||
|
||||
@Size(max = 20)
|
||||
@ColumnDefault("'0'")
|
||||
@Column(name = "fit_state", length = 20)
|
||||
private String fitState;
|
||||
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "fit_state_dttm")
|
||||
private OffsetDateTime fitStateDttm;
|
||||
|
||||
@Column(name = "labeler_uid")
|
||||
private Long labelerUid;
|
||||
|
||||
@Size(max = 20)
|
||||
@ColumnDefault("'0'")
|
||||
@Column(name = "label_state", length = 20)
|
||||
private String labelState;
|
||||
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "label_state_dttm")
|
||||
private OffsetDateTime labelStateDttm;
|
||||
|
||||
@Column(name = "tester_uid")
|
||||
private Long testerUid;
|
||||
|
||||
@Size(max = 20)
|
||||
@ColumnDefault("'0'")
|
||||
@Column(name = "test_state", length = 20)
|
||||
private String testState;
|
||||
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "test_state_dttm")
|
||||
private OffsetDateTime testStateDttm;
|
||||
|
||||
@Column(name = "fit_state_cmmnt", length = Integer.MAX_VALUE)
|
||||
private String fitStateCmmnt;
|
||||
|
||||
@Column(name = "ref_map_sheet_num")
|
||||
private Long refMapSheetNum;
|
||||
|
||||
@ColumnDefault("uuid_generate_v4()")
|
||||
@Column(name = "uuid")
|
||||
private UUID uuid;
|
||||
|
||||
@Column(name = "stage")
|
||||
private Integer stage;
|
||||
|
||||
@Column(name = "map_5k_id")
|
||||
private Long map5kId;
|
||||
|
||||
@Column(name = "file_created_yn")
|
||||
private Boolean fileCreatedYn;
|
||||
|
||||
|
||||
@Column(name = "geom", columnDefinition = "geometry")
|
||||
private Geometry geom;
|
||||
|
||||
|
||||
@Column(name = "geom_center", columnDefinition = "geometry")
|
||||
private Geometry geomCenter;
|
||||
|
||||
|
||||
@Column(name = "before_geom", columnDefinition = "geometry")
|
||||
private Geometry beforeGeom;
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.InferenceResultEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface InferenceResultRepository
|
||||
extends JpaRepository<MapSheetAnalEntity, Long>, InferenceResultRepositoryCustom {}
|
||||
extends JpaRepository<InferenceResultEntity, Long>, InferenceResultRepositoryCustom {}
|
||||
|
||||
@@ -1,31 +1,9 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.SearchGeoReq;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataGeomEntity;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.hibernate.ScrollableResults;
|
||||
|
||||
public interface InferenceResultRepositoryCustom {
|
||||
|
||||
Page<InferenceResultDto.AnalResList> getInferenceResultList(
|
||||
InferenceResultDto.SearchReq searchReq);
|
||||
ScrollableResults scrollAllOrdered(int fetchSize);
|
||||
|
||||
Optional<InferenceResultDto.AnalResSummary> getInferenceResultSummary(Long id);
|
||||
|
||||
Page<InferenceResultDto.Geom> getInferenceGeomList(
|
||||
Long id, InferenceResultDto.SearchGeoReq searchGeoReq);
|
||||
|
||||
Page<MapSheetAnalDataGeomEntity> listInferenceResultWithGeom(
|
||||
List<Long> dataIds, SearchGeoReq searchReq);
|
||||
|
||||
List<Long> getSheets(Long id);
|
||||
|
||||
List<Dashboard> getDashboard(Long id);
|
||||
|
||||
List<MapSheetAnalDataEntity> listAnalyGeom(@NotNull Long id);
|
||||
}
|
||||
|
||||
@@ -1,27 +1,13 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.SearchGeoReq;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.*;
|
||||
import com.querydsl.core.BooleanBuilder;
|
||||
import com.querydsl.core.types.Order;
|
||||
import com.querydsl.core.types.OrderSpecifier;
|
||||
import com.querydsl.core.types.Projections;
|
||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||
import com.querydsl.core.types.dsl.Expressions;
|
||||
import com.querydsl.jpa.JPAExpressions;
|
||||
import com.querydsl.jpa.JPQLQuery;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.InferenceResultEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.QInferenceResultEntity;
|
||||
import com.querydsl.jpa.impl.JPAQuery;
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.query.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@@ -29,335 +15,27 @@ import org.springframework.stereotype.Repository;
|
||||
public class InferenceResultRepositoryImpl implements InferenceResultRepositoryCustom {
|
||||
|
||||
private final JPAQueryFactory queryFactory;
|
||||
private final QModelMngBakEntity tmm = QModelMngBakEntity.modelMngBakEntity;
|
||||
private final QModelVerEntity tmv = QModelVerEntity.modelVerEntity;
|
||||
private final QMapSheetAnalEntity mapSheetAnalEntity = QMapSheetAnalEntity.mapSheetAnalEntity;
|
||||
private final QMapSheetAnalDataEntity mapSheetAnalDataEntity =
|
||||
QMapSheetAnalDataEntity.mapSheetAnalDataEntity;
|
||||
private final QMapSheetAnalDataGeomEntity mapSheetAnalDataGeomEntity =
|
||||
QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
|
||||
private final QMapSheetAnalSttcEntity mapSheetAnalSttcEntity =
|
||||
QMapSheetAnalSttcEntity.mapSheetAnalSttcEntity;
|
||||
|
||||
/**
|
||||
* 분석결과 목록 조회
|
||||
*
|
||||
* @param searchReq
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Page<InferenceResultDto.AnalResList> getInferenceResultList(
|
||||
InferenceResultDto.SearchReq searchReq) {
|
||||
Pageable pageable = searchReq.toPageable();
|
||||
// "0000" 전체조회
|
||||
BooleanBuilder builder = new BooleanBuilder();
|
||||
if (searchReq.getStatCode() != null && !"0000".equals(searchReq.getStatCode())) {
|
||||
builder.and(mapSheetAnalEntity.analState.eq(searchReq.getStatCode()));
|
||||
}
|
||||
public ScrollableResults scrollAllOrdered(int fetchSize) {
|
||||
QInferenceResultEntity e = QInferenceResultEntity.inferenceResultEntity;
|
||||
|
||||
// 제목
|
||||
if (searchReq.getTitle() != null) {
|
||||
builder.and(mapSheetAnalEntity.analTitle.like("%" + searchReq.getTitle() + "%"));
|
||||
}
|
||||
JPAQuery<InferenceResultEntity> q =
|
||||
queryFactory
|
||||
.selectFrom(e)
|
||||
.orderBy(
|
||||
e.stage.asc(),
|
||||
e.mapId.asc(),
|
||||
e.input1.asc(),
|
||||
e.input2.asc(),
|
||||
e.id.asc()
|
||||
);
|
||||
|
||||
List<InferenceResultDto.AnalResList> content =
|
||||
queryFactory
|
||||
.select(
|
||||
Projections.constructor(
|
||||
InferenceResultDto.AnalResList.class,
|
||||
mapSheetAnalEntity.id,
|
||||
mapSheetAnalEntity.analTitle,
|
||||
mapSheetAnalEntity.analMapSheet,
|
||||
mapSheetAnalEntity.detectingCnt,
|
||||
mapSheetAnalEntity.analStrtDttm,
|
||||
mapSheetAnalEntity.analEndDttm,
|
||||
mapSheetAnalEntity.analSec,
|
||||
mapSheetAnalEntity.analPredSec,
|
||||
mapSheetAnalEntity.analState,
|
||||
Expressions.stringTemplate(
|
||||
"fn_code_name({0}, {1})", "0002", mapSheetAnalEntity.analState),
|
||||
mapSheetAnalEntity.gukyuinUsed))
|
||||
.from(mapSheetAnalEntity)
|
||||
.where(builder)
|
||||
.offset(pageable.getOffset())
|
||||
.limit(pageable.getPageSize())
|
||||
.orderBy(mapSheetAnalEntity.id.desc())
|
||||
.fetch();
|
||||
// QueryDSL -> Hibernate Query로 unwrap 해서 커서 스트리밍
|
||||
Query<?> hQuery = q.createQuery().unwrap(Query.class);
|
||||
|
||||
long total =
|
||||
queryFactory
|
||||
.select(mapSheetAnalEntity.id)
|
||||
.from(mapSheetAnalEntity)
|
||||
.where(builder)
|
||||
.fetchCount();
|
||||
|
||||
return new PageImpl<>(content, pageable, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 분석결과 요약정보
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Optional<InferenceResultDto.AnalResSummary> getInferenceResultSummary(Long id) {
|
||||
|
||||
// 1. 최신 버전 UID를 가져오는 서브쿼리
|
||||
JPQLQuery<Long> latestVerUidSub =
|
||||
JPAExpressions.select(tmv.id.max()).from(tmv).where(tmv.modelUid.eq(tmm.id));
|
||||
|
||||
Optional<InferenceResultDto.AnalResSummary> content =
|
||||
Optional.ofNullable(
|
||||
queryFactory
|
||||
.select(
|
||||
Projections.constructor(
|
||||
InferenceResultDto.AnalResSummary.class,
|
||||
mapSheetAnalEntity.id,
|
||||
mapSheetAnalEntity.analTitle,
|
||||
tmm.modelNm.concat(" ").concat(tmv.modelVer).as("modelInfo"),
|
||||
mapSheetAnalEntity.targetYyyy,
|
||||
mapSheetAnalEntity.compareYyyy,
|
||||
mapSheetAnalEntity.analMapSheet,
|
||||
mapSheetAnalEntity.analStrtDttm,
|
||||
mapSheetAnalEntity.analEndDttm,
|
||||
mapSheetAnalEntity.analSec,
|
||||
mapSheetAnalEntity.analPredSec,
|
||||
mapSheetAnalEntity.resultUrl,
|
||||
mapSheetAnalEntity.detectingCnt,
|
||||
mapSheetAnalEntity.accuracy,
|
||||
mapSheetAnalEntity.analState,
|
||||
Expressions.stringTemplate(
|
||||
"fn_code_name({0}, {1})", "0002", mapSheetAnalEntity.analState)))
|
||||
.from(mapSheetAnalEntity)
|
||||
.leftJoin(tmm)
|
||||
.on(mapSheetAnalEntity.modelUid.eq(tmm.id))
|
||||
.leftJoin(tmv)
|
||||
.on(tmv.modelUid.eq(tmm.id).and(tmv.id.eq(latestVerUidSub)))
|
||||
.where(mapSheetAnalEntity.id.eq(id))
|
||||
.fetchOne());
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* 분석결과 상세 class name별 탐지 개수
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<Dashboard> getDashboard(Long id) {
|
||||
return queryFactory
|
||||
.select(
|
||||
Projections.constructor(
|
||||
Dashboard.class,
|
||||
mapSheetAnalSttcEntity.id.classAfterCd,
|
||||
mapSheetAnalSttcEntity.classAfterCnt.sum()))
|
||||
.from(mapSheetAnalSttcEntity)
|
||||
.where(mapSheetAnalSttcEntity.id.analUid.eq(id))
|
||||
.groupBy(mapSheetAnalSttcEntity.id.classAfterCd)
|
||||
.orderBy(mapSheetAnalSttcEntity.id.classAfterCd.asc())
|
||||
.fetch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MapSheetAnalDataEntity> listAnalyGeom(Long id) {
|
||||
QMapSheetAnalDataEntity analy = QMapSheetAnalDataEntity.mapSheetAnalDataEntity;
|
||||
return queryFactory.selectFrom(analy).where(analy.analUid.eq(id)).fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 분석결과 상세 목록
|
||||
*
|
||||
* @param searchReq
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Page<MapSheetAnalDataGeomEntity> listInferenceResultWithGeom(
|
||||
List<Long> ids, SearchGeoReq searchReq) {
|
||||
|
||||
// 분석 차수
|
||||
QMapSheetAnalDataGeomEntity detectedEntity =
|
||||
QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
|
||||
Pageable pageable = searchReq.toPageable();
|
||||
|
||||
// 검색조건
|
||||
JPAQuery<MapSheetAnalDataGeomEntity> query =
|
||||
queryFactory
|
||||
.selectFrom(detectedEntity)
|
||||
.where(
|
||||
detectedEntity.dataUid.in(ids),
|
||||
eqTargetClass(detectedEntity, searchReq.getTargetClass()),
|
||||
eqCompareClass(detectedEntity, searchReq.getCompareClass()),
|
||||
containsMapSheetNum(detectedEntity, searchReq.getMapSheetNum()));
|
||||
|
||||
// count
|
||||
long total = query.fetchCount();
|
||||
|
||||
// Pageable에서 정렬 가져오기, 없으면 기본 정렬(createdDttm desc) 사용
|
||||
List<OrderSpecifier<?>> orders = getOrderSpecifiers(pageable.getSort());
|
||||
if (orders.isEmpty()) {
|
||||
orders.add(detectedEntity.createdDttm.desc());
|
||||
}
|
||||
|
||||
List<MapSheetAnalDataGeomEntity> content =
|
||||
query
|
||||
.offset(pageable.getOffset())
|
||||
.limit(pageable.getPageSize())
|
||||
.orderBy(orders.toArray(new OrderSpecifier[0]))
|
||||
.fetch();
|
||||
|
||||
return new PageImpl<>(content, pageable, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 분석결과 상세 목록
|
||||
*
|
||||
* @param searchGeoReq
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Page<InferenceResultDto.Geom> getInferenceGeomList(Long id, SearchGeoReq searchGeoReq) {
|
||||
Pageable pageable = searchGeoReq.toPageable();
|
||||
BooleanBuilder builder = new BooleanBuilder();
|
||||
|
||||
// 추론결과 id
|
||||
builder.and(mapSheetAnalEntity.id.eq(id));
|
||||
|
||||
// 기준년도 분류
|
||||
if (searchGeoReq.getTargetClass() != null && !searchGeoReq.getTargetClass().equals("")) {
|
||||
builder.and(
|
||||
mapSheetAnalDataGeomEntity
|
||||
.classAfterCd
|
||||
.toLowerCase()
|
||||
.eq(searchGeoReq.getTargetClass().toLowerCase()));
|
||||
}
|
||||
|
||||
// 비교년도 분류
|
||||
if (searchGeoReq.getCompareClass() != null && !searchGeoReq.getCompareClass().equals("")) {
|
||||
builder.and(
|
||||
mapSheetAnalDataGeomEntity
|
||||
.classBeforeCd
|
||||
.toLowerCase()
|
||||
.eq(searchGeoReq.getCompareClass().toLowerCase()));
|
||||
}
|
||||
|
||||
// 분석도엽
|
||||
if (searchGeoReq.getMapSheetNum() != null && !searchGeoReq.getMapSheetNum().isEmpty()) {
|
||||
List<Long> mapSheetNum = searchGeoReq.getMapSheetNum();
|
||||
builder.and(mapSheetAnalDataGeomEntity.mapSheetNum.in(mapSheetNum));
|
||||
}
|
||||
|
||||
List<InferenceResultDto.Geom> content =
|
||||
queryFactory
|
||||
.select(
|
||||
Projections.constructor(
|
||||
InferenceResultDto.Geom.class,
|
||||
mapSheetAnalDataGeomEntity.compareYyyy,
|
||||
mapSheetAnalDataGeomEntity.targetYyyy,
|
||||
mapSheetAnalDataGeomEntity.classBeforeCd,
|
||||
mapSheetAnalDataGeomEntity.classBeforeProb,
|
||||
mapSheetAnalDataGeomEntity.classAfterCd,
|
||||
mapSheetAnalDataGeomEntity.classAfterProb,
|
||||
mapSheetAnalDataGeomEntity.mapSheetNum,
|
||||
mapSheetAnalDataGeomEntity.geom,
|
||||
mapSheetAnalDataGeomEntity.geomCenter))
|
||||
.from(mapSheetAnalEntity)
|
||||
.join(mapSheetAnalDataEntity)
|
||||
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
||||
.join(mapSheetAnalDataGeomEntity)
|
||||
.on(mapSheetAnalDataGeomEntity.dataUid.eq(mapSheetAnalDataEntity.id))
|
||||
.where(builder)
|
||||
.offset(pageable.getOffset())
|
||||
.limit(pageable.getPageSize())
|
||||
.fetch();
|
||||
|
||||
long total =
|
||||
queryFactory
|
||||
.select(mapSheetAnalDataGeomEntity.id)
|
||||
.from(mapSheetAnalEntity)
|
||||
.join(mapSheetAnalDataEntity)
|
||||
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
||||
.join(mapSheetAnalDataGeomEntity)
|
||||
.on(mapSheetAnalDataGeomEntity.dataUid.eq(mapSheetAnalDataEntity.id))
|
||||
.where(builder)
|
||||
.fetchCount();
|
||||
|
||||
return new PageImpl<>(content, pageable, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 추론된 5000:1 도엽 목록
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<Long> getSheets(Long id) {
|
||||
return queryFactory
|
||||
.select(mapSheetAnalDataEntity.mapSheetNum)
|
||||
.from(mapSheetAnalEntity)
|
||||
.join(mapSheetAnalDataEntity)
|
||||
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
||||
.where(mapSheetAnalEntity.id.eq(id))
|
||||
.groupBy(mapSheetAnalDataEntity.mapSheetNum)
|
||||
.fetch();
|
||||
}
|
||||
|
||||
/** Pageable의 Sort를 QueryDSL OrderSpecifier로 변환 */
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private List<OrderSpecifier<?>> getOrderSpecifiers(Sort sort) {
|
||||
List<OrderSpecifier<?>> orders = new ArrayList<>();
|
||||
|
||||
if (sort.isSorted()) {
|
||||
QMapSheetAnalDataGeomEntity entity = QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
|
||||
|
||||
for (Sort.Order order : sort) {
|
||||
Order direction = order.isAscending() ? Order.ASC : Order.DESC;
|
||||
String property = order.getProperty();
|
||||
|
||||
// 유효한 필드만 처리
|
||||
switch (property) {
|
||||
case "classBeforeCd" -> orders.add(new OrderSpecifier(direction, entity.classBeforeCd));
|
||||
case "classBeforeProb" ->
|
||||
orders.add(new OrderSpecifier(direction, entity.classBeforeProb));
|
||||
case "classAfterCd" -> orders.add(new OrderSpecifier(direction, entity.classAfterCd));
|
||||
case "classAfterProb" -> orders.add(new OrderSpecifier(direction, entity.classAfterProb));
|
||||
case "mapSheetNum" -> orders.add(new OrderSpecifier(direction, entity.mapSheetNum));
|
||||
case "compareYyyy" -> orders.add(new OrderSpecifier(direction, entity.compareYyyy));
|
||||
case "targetYyyy" -> orders.add(new OrderSpecifier(direction, entity.targetYyyy));
|
||||
case "area" -> orders.add(new OrderSpecifier(direction, entity.area));
|
||||
case "createdDttm" -> orders.add(new OrderSpecifier(direction, entity.createdDttm));
|
||||
case "updatedDttm" -> orders.add(new OrderSpecifier(direction, entity.updatedDttm));
|
||||
// 유효하지 않은 필드는 무시
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return orders;
|
||||
}
|
||||
|
||||
private BooleanExpression eqTargetClass(
|
||||
QMapSheetAnalDataGeomEntity detectedEntity, String targetClass) {
|
||||
return targetClass != null && !targetClass.isEmpty()
|
||||
? detectedEntity.classAfterCd.toLowerCase().eq(targetClass.toLowerCase())
|
||||
: null;
|
||||
}
|
||||
|
||||
private BooleanExpression eqCompareClass(
|
||||
QMapSheetAnalDataGeomEntity detectedEntity, String compareClass) {
|
||||
return compareClass != null && !compareClass.isEmpty()
|
||||
? detectedEntity.classBeforeCd.toLowerCase().eq(compareClass.toLowerCase())
|
||||
: null;
|
||||
}
|
||||
|
||||
private BooleanExpression containsMapSheetNum(
|
||||
QMapSheetAnalDataGeomEntity detectedEntity, List<Long> mapSheet) {
|
||||
if (mapSheet == null || mapSheet.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return detectedEntity.mapSheetNum.in(mapSheet);
|
||||
return hQuery
|
||||
.setReadOnly(true)
|
||||
.setFetchSize(fetchSize) // PostgreSQL 커서/스트리밍에 영향
|
||||
.scroll(ScrollMode.FORWARD_ONLY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface MapSheetAnalDataInferenceGeomRepository
|
||||
extends JpaRepository<MapSheetAnalDataInferenceGeomEntity, Long>,
|
||||
MapSheetAnalDataInferenceGeomRepositoryCustom {}
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
public interface MapSheetAnalDataInferenceGeomRepositoryCustom {}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class MapSheetAnalDataInferenceGeomRepositoryImpl
|
||||
implements MapSheetAnalDataInferenceGeomRepositoryCustom {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface MapSheetAnalDataInferenceRepository
|
||||
extends JpaRepository<MapSheetAnalDataInferenceEntity, Long>,
|
||||
MapSheetAnalDataInferenceRepositoryCustom {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
public interface MapSheetAnalDataInferenceRepositoryCustom {}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class MapSheetAnalDataInferenceRepositoryImpl
|
||||
implements MapSheetAnalDataInferenceRepositoryCustom {
|
||||
|
||||
private final JPAQueryFactory queryFactory;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface MapSheetAnalDataRepository
|
||||
extends JpaRepository<MapSheetAnalEntity, Long>, MapSheetAnalDataRepositoryCustom {}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.AnalResList;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.AnalResSummary;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.SearchGeoReq;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataGeomEntity;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
public interface MapSheetAnalDataRepositoryCustom {
|
||||
|
||||
Page<AnalResList> getInferenceResultList(InferenceResultDto.SearchReq searchReq);
|
||||
|
||||
Optional<AnalResSummary> getInferenceResultSummary(Long id);
|
||||
|
||||
Page<InferenceResultDto.Geom> getInferenceGeomList(
|
||||
Long id, InferenceResultDto.SearchGeoReq searchGeoReq);
|
||||
|
||||
Page<MapSheetAnalDataGeomEntity> listInferenceResultWithGeom(
|
||||
List<Long> dataIds, SearchGeoReq searchReq);
|
||||
|
||||
List<Long> getSheets(Long id);
|
||||
|
||||
List<Dashboard> getDashboard(Long id);
|
||||
|
||||
List<MapSheetAnalDataEntity> listAnalyGeom(@NotNull Long id);
|
||||
}
|
||||
@@ -0,0 +1,371 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.Inference;
|
||||
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.AnalResList;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.AnalResSummary;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.SearchGeoReq;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataGeomEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataGeomEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalSttcEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.QModelMngBakEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.QModelVerEntity;
|
||||
import com.querydsl.core.BooleanBuilder;
|
||||
import com.querydsl.core.types.Order;
|
||||
import com.querydsl.core.types.OrderSpecifier;
|
||||
import com.querydsl.core.types.Projections;
|
||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||
import com.querydsl.core.types.dsl.Expressions;
|
||||
import com.querydsl.jpa.JPAExpressions;
|
||||
import com.querydsl.jpa.JPQLQuery;
|
||||
import com.querydsl.jpa.impl.JPAQuery;
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class MapSheetAnalDataRepositoryImpl implements MapSheetAnalDataRepositoryCustom {
|
||||
|
||||
private final JPAQueryFactory queryFactory;
|
||||
private final QModelMngBakEntity tmm = QModelMngBakEntity.modelMngBakEntity;
|
||||
private final QModelVerEntity tmv = QModelVerEntity.modelVerEntity;
|
||||
private final QMapSheetAnalEntity mapSheetAnalEntity = QMapSheetAnalEntity.mapSheetAnalEntity;
|
||||
private final QMapSheetAnalDataEntity mapSheetAnalDataEntity =
|
||||
QMapSheetAnalDataEntity.mapSheetAnalDataEntity;
|
||||
private final QMapSheetAnalDataGeomEntity mapSheetAnalDataGeomEntity =
|
||||
QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
|
||||
private final QMapSheetAnalSttcEntity mapSheetAnalSttcEntity =
|
||||
QMapSheetAnalSttcEntity.mapSheetAnalSttcEntity;
|
||||
|
||||
/**
|
||||
* 분석결과 목록 조회
|
||||
*
|
||||
* @param searchReq
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Page<AnalResList> getInferenceResultList(InferenceResultDto.SearchReq searchReq) {
|
||||
Pageable pageable = searchReq.toPageable();
|
||||
// "0000" 전체조회
|
||||
BooleanBuilder builder = new BooleanBuilder();
|
||||
if (searchReq.getStatCode() != null && !"0000".equals(searchReq.getStatCode())) {
|
||||
builder.and(mapSheetAnalEntity.analState.eq(searchReq.getStatCode()));
|
||||
}
|
||||
|
||||
// 제목
|
||||
if (searchReq.getTitle() != null) {
|
||||
builder.and(mapSheetAnalEntity.analTitle.like("%" + searchReq.getTitle() + "%"));
|
||||
}
|
||||
|
||||
List<AnalResList> content =
|
||||
queryFactory
|
||||
.select(
|
||||
Projections.constructor(
|
||||
InferenceResultDto.AnalResList.class,
|
||||
mapSheetAnalEntity.id,
|
||||
mapSheetAnalEntity.analTitle,
|
||||
mapSheetAnalEntity.analMapSheet,
|
||||
mapSheetAnalEntity.detectingCnt,
|
||||
mapSheetAnalEntity.analStrtDttm,
|
||||
mapSheetAnalEntity.analEndDttm,
|
||||
mapSheetAnalEntity.analSec,
|
||||
mapSheetAnalEntity.analPredSec,
|
||||
mapSheetAnalEntity.analState,
|
||||
Expressions.stringTemplate(
|
||||
"fn_code_name({0}, {1})", "0002", mapSheetAnalEntity.analState),
|
||||
mapSheetAnalEntity.gukyuinUsed))
|
||||
.from(mapSheetAnalEntity)
|
||||
.where(builder)
|
||||
.offset(pageable.getOffset())
|
||||
.limit(pageable.getPageSize())
|
||||
.orderBy(mapSheetAnalEntity.id.desc())
|
||||
.fetch();
|
||||
|
||||
long total =
|
||||
queryFactory
|
||||
.select(mapSheetAnalEntity.id)
|
||||
.from(mapSheetAnalEntity)
|
||||
.where(builder)
|
||||
.fetchCount();
|
||||
|
||||
return new PageImpl<>(content, pageable, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 분석결과 요약정보
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Optional<AnalResSummary> getInferenceResultSummary(Long id) {
|
||||
|
||||
// 1. 최신 버전 UID를 가져오는 서브쿼리
|
||||
JPQLQuery<Long> latestVerUidSub =
|
||||
JPAExpressions.select(tmv.id.max()).from(tmv).where(tmv.modelUid.eq(tmm.id));
|
||||
|
||||
Optional<InferenceResultDto.AnalResSummary> content =
|
||||
Optional.ofNullable(
|
||||
queryFactory
|
||||
.select(
|
||||
Projections.constructor(
|
||||
InferenceResultDto.AnalResSummary.class,
|
||||
mapSheetAnalEntity.id,
|
||||
mapSheetAnalEntity.analTitle,
|
||||
tmm.modelNm.concat(" ").concat(tmv.modelVer).as("modelInfo"),
|
||||
mapSheetAnalEntity.targetYyyy,
|
||||
mapSheetAnalEntity.compareYyyy,
|
||||
mapSheetAnalEntity.analMapSheet,
|
||||
mapSheetAnalEntity.analStrtDttm,
|
||||
mapSheetAnalEntity.analEndDttm,
|
||||
mapSheetAnalEntity.analSec,
|
||||
mapSheetAnalEntity.analPredSec,
|
||||
mapSheetAnalEntity.resultUrl,
|
||||
mapSheetAnalEntity.detectingCnt,
|
||||
mapSheetAnalEntity.accuracy,
|
||||
mapSheetAnalEntity.analState,
|
||||
Expressions.stringTemplate(
|
||||
"fn_code_name({0}, {1})", "0002", mapSheetAnalEntity.analState)))
|
||||
.from(mapSheetAnalEntity)
|
||||
.leftJoin(tmm)
|
||||
.on(mapSheetAnalEntity.modelUid.eq(tmm.id))
|
||||
.leftJoin(tmv)
|
||||
.on(tmv.modelUid.eq(tmm.id).and(tmv.id.eq(latestVerUidSub)))
|
||||
.where(mapSheetAnalEntity.id.eq(id))
|
||||
.fetchOne());
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* 분석결과 상세 class name별 탐지 개수
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<Dashboard> getDashboard(Long id) {
|
||||
return queryFactory
|
||||
.select(
|
||||
Projections.constructor(
|
||||
Dashboard.class,
|
||||
mapSheetAnalSttcEntity.id.classAfterCd,
|
||||
mapSheetAnalSttcEntity.classAfterCnt.sum()))
|
||||
.from(mapSheetAnalSttcEntity)
|
||||
.where(mapSheetAnalSttcEntity.id.analUid.eq(id))
|
||||
.groupBy(mapSheetAnalSttcEntity.id.classAfterCd)
|
||||
.orderBy(mapSheetAnalSttcEntity.id.classAfterCd.asc())
|
||||
.fetch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MapSheetAnalDataEntity> listAnalyGeom(Long id) {
|
||||
QMapSheetAnalDataEntity analy = QMapSheetAnalDataEntity.mapSheetAnalDataEntity;
|
||||
return queryFactory.selectFrom(analy).where(analy.analUid.eq(id)).fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 분석결과 상세 목록
|
||||
*
|
||||
* @param searchReq
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Page<MapSheetAnalDataGeomEntity> listInferenceResultWithGeom(
|
||||
List<Long> ids, SearchGeoReq searchReq) {
|
||||
|
||||
// 분석 차수
|
||||
QMapSheetAnalDataGeomEntity detectedEntity =
|
||||
QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
|
||||
Pageable pageable = searchReq.toPageable();
|
||||
|
||||
// 검색조건
|
||||
JPAQuery<MapSheetAnalDataGeomEntity> query =
|
||||
queryFactory
|
||||
.selectFrom(detectedEntity)
|
||||
.where(
|
||||
detectedEntity.dataUid.in(ids),
|
||||
eqTargetClass(detectedEntity, searchReq.getTargetClass()),
|
||||
eqCompareClass(detectedEntity, searchReq.getCompareClass()),
|
||||
containsMapSheetNum(detectedEntity, searchReq.getMapSheetNum()));
|
||||
|
||||
// count
|
||||
long total = query.fetchCount();
|
||||
|
||||
// Pageable에서 정렬 가져오기, 없으면 기본 정렬(createdDttm desc) 사용
|
||||
List<OrderSpecifier<?>> orders = getOrderSpecifiers(pageable.getSort());
|
||||
if (orders.isEmpty()) {
|
||||
orders.add(detectedEntity.createdDttm.desc());
|
||||
}
|
||||
|
||||
List<MapSheetAnalDataGeomEntity> content =
|
||||
query
|
||||
.offset(pageable.getOffset())
|
||||
.limit(pageable.getPageSize())
|
||||
.orderBy(orders.toArray(new OrderSpecifier[0]))
|
||||
.fetch();
|
||||
|
||||
return new PageImpl<>(content, pageable, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 분석결과 상세 목록
|
||||
*
|
||||
* @param searchGeoReq
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Page<InferenceResultDto.Geom> getInferenceGeomList(Long id, SearchGeoReq searchGeoReq) {
|
||||
Pageable pageable = searchGeoReq.toPageable();
|
||||
BooleanBuilder builder = new BooleanBuilder();
|
||||
|
||||
// 추론결과 id
|
||||
builder.and(mapSheetAnalEntity.id.eq(id));
|
||||
|
||||
// 기준년도 분류
|
||||
if (searchGeoReq.getTargetClass() != null && !searchGeoReq.getTargetClass().equals("")) {
|
||||
builder.and(
|
||||
mapSheetAnalDataGeomEntity
|
||||
.classAfterCd
|
||||
.toLowerCase()
|
||||
.eq(searchGeoReq.getTargetClass().toLowerCase()));
|
||||
}
|
||||
|
||||
// 비교년도 분류
|
||||
if (searchGeoReq.getCompareClass() != null && !searchGeoReq.getCompareClass().equals("")) {
|
||||
builder.and(
|
||||
mapSheetAnalDataGeomEntity
|
||||
.classBeforeCd
|
||||
.toLowerCase()
|
||||
.eq(searchGeoReq.getCompareClass().toLowerCase()));
|
||||
}
|
||||
|
||||
// 분석도엽
|
||||
if (searchGeoReq.getMapSheetNum() != null && !searchGeoReq.getMapSheetNum().isEmpty()) {
|
||||
List<Long> mapSheetNum = searchGeoReq.getMapSheetNum();
|
||||
builder.and(mapSheetAnalDataGeomEntity.mapSheetNum.in(mapSheetNum));
|
||||
}
|
||||
|
||||
List<InferenceResultDto.Geom> content =
|
||||
queryFactory
|
||||
.select(
|
||||
Projections.constructor(
|
||||
InferenceResultDto.Geom.class,
|
||||
mapSheetAnalDataGeomEntity.compareYyyy,
|
||||
mapSheetAnalDataGeomEntity.targetYyyy,
|
||||
mapSheetAnalDataGeomEntity.classBeforeCd,
|
||||
mapSheetAnalDataGeomEntity.classBeforeProb,
|
||||
mapSheetAnalDataGeomEntity.classAfterCd,
|
||||
mapSheetAnalDataGeomEntity.classAfterProb,
|
||||
mapSheetAnalDataGeomEntity.mapSheetNum,
|
||||
mapSheetAnalDataGeomEntity.geom,
|
||||
mapSheetAnalDataGeomEntity.geomCenter))
|
||||
.from(mapSheetAnalEntity)
|
||||
.join(mapSheetAnalDataEntity)
|
||||
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
||||
.join(mapSheetAnalDataGeomEntity)
|
||||
.on(mapSheetAnalDataGeomEntity.dataUid.eq(mapSheetAnalDataEntity.id))
|
||||
.where(builder)
|
||||
.offset(pageable.getOffset())
|
||||
.limit(pageable.getPageSize())
|
||||
.fetch();
|
||||
|
||||
long total =
|
||||
queryFactory
|
||||
.select(mapSheetAnalDataGeomEntity.id)
|
||||
.from(mapSheetAnalEntity)
|
||||
.join(mapSheetAnalDataEntity)
|
||||
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
||||
.join(mapSheetAnalDataGeomEntity)
|
||||
.on(mapSheetAnalDataGeomEntity.dataUid.eq(mapSheetAnalDataEntity.id))
|
||||
.where(builder)
|
||||
.fetchCount();
|
||||
|
||||
return new PageImpl<>(content, pageable, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 추론된 5000:1 도엽 목록
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<Long> getSheets(Long id) {
|
||||
return queryFactory
|
||||
.select(mapSheetAnalDataEntity.mapSheetNum)
|
||||
.from(mapSheetAnalEntity)
|
||||
.join(mapSheetAnalDataEntity)
|
||||
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
||||
.where(mapSheetAnalEntity.id.eq(id))
|
||||
.groupBy(mapSheetAnalDataEntity.mapSheetNum)
|
||||
.fetch();
|
||||
}
|
||||
|
||||
/** Pageable의 Sort를 QueryDSL OrderSpecifier로 변환 */
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private List<OrderSpecifier<?>> getOrderSpecifiers(Sort sort) {
|
||||
List<OrderSpecifier<?>> orders = new ArrayList<>();
|
||||
|
||||
if (sort.isSorted()) {
|
||||
QMapSheetAnalDataGeomEntity entity = QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
|
||||
|
||||
for (Sort.Order order : sort) {
|
||||
Order direction = order.isAscending() ? Order.ASC : Order.DESC;
|
||||
String property = order.getProperty();
|
||||
|
||||
// 유효한 필드만 처리
|
||||
switch (property) {
|
||||
case "classBeforeCd" -> orders.add(new OrderSpecifier(direction, entity.classBeforeCd));
|
||||
case "classBeforeProb" ->
|
||||
orders.add(new OrderSpecifier(direction, entity.classBeforeProb));
|
||||
case "classAfterCd" -> orders.add(new OrderSpecifier(direction, entity.classAfterCd));
|
||||
case "classAfterProb" -> orders.add(new OrderSpecifier(direction, entity.classAfterProb));
|
||||
case "mapSheetNum" -> orders.add(new OrderSpecifier(direction, entity.mapSheetNum));
|
||||
case "compareYyyy" -> orders.add(new OrderSpecifier(direction, entity.compareYyyy));
|
||||
case "targetYyyy" -> orders.add(new OrderSpecifier(direction, entity.targetYyyy));
|
||||
case "area" -> orders.add(new OrderSpecifier(direction, entity.area));
|
||||
case "createdDttm" -> orders.add(new OrderSpecifier(direction, entity.createdDttm));
|
||||
case "updatedDttm" -> orders.add(new OrderSpecifier(direction, entity.updatedDttm));
|
||||
// 유효하지 않은 필드는 무시
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return orders;
|
||||
}
|
||||
|
||||
private BooleanExpression eqTargetClass(
|
||||
QMapSheetAnalDataGeomEntity detectedEntity, String targetClass) {
|
||||
return targetClass != null && !targetClass.isEmpty()
|
||||
? detectedEntity.classAfterCd.toLowerCase().eq(targetClass.toLowerCase())
|
||||
: null;
|
||||
}
|
||||
|
||||
private BooleanExpression eqCompareClass(
|
||||
QMapSheetAnalDataGeomEntity detectedEntity, String compareClass) {
|
||||
return compareClass != null && !compareClass.isEmpty()
|
||||
? detectedEntity.classBeforeCd.toLowerCase().eq(compareClass.toLowerCase())
|
||||
: null;
|
||||
}
|
||||
|
||||
private BooleanExpression containsMapSheetNum(
|
||||
QMapSheetAnalDataGeomEntity detectedEntity, List<Long> mapSheet) {
|
||||
if (mapSheet == null || mapSheet.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return detectedEntity.mapSheetNum.in(mapSheet);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user