데이터셋 API 커밋

This commit is contained in:
2026-02-03 18:51:56 +09:00
parent 19644e5c9f
commit f1ad59d0b1
13 changed files with 658 additions and 59 deletions

View File

@@ -2,11 +2,18 @@ package com.kamco.cd.training.postgres.core;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kamco.cd.training.common.enums.LearnDataRegister;
import com.kamco.cd.training.common.enums.LearnDataType;
import com.kamco.cd.training.common.exception.NotFoundException;
import com.kamco.cd.training.common.service.BaseCoreService;
import com.kamco.cd.training.dataset.dto.DatasetDto;
import com.kamco.cd.training.dataset.dto.DatasetDto.SelectDataSet;
import com.kamco.cd.training.dataset.dto.DatasetObjDto.Basic;
import com.kamco.cd.training.dataset.dto.DatasetObjDto.SearchReq;
import com.kamco.cd.training.model.dto.ModelMngDto;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import com.kamco.cd.training.postgres.entity.DatasetObjEntity;
import com.kamco.cd.training.postgres.repository.dataset.DatasetObjRepository;
import com.kamco.cd.training.postgres.repository.dataset.DatasetRepository;
import java.time.ZonedDateTime;
import java.util.HashMap;
@@ -25,6 +32,7 @@ import org.springframework.stereotype.Service;
public class DatasetCoreService
implements BaseCoreService<DatasetDto.Basic, Long, DatasetDto.SearchReq> {
private final DatasetRepository datasetRepository;
private final DatasetObjRepository datasetObjRepository;
private final ObjectMapper objectMapper;
/**
@@ -99,25 +107,25 @@ public class DatasetCoreService
// 먼저 id1 필드를 임시값(0)으로 설정하여 저장
DatasetEntity entity = new DatasetEntity();
entity.setTitle(registerReq.getTitle());
entity.setYear(registerReq.getYear());
entity.setGroupTitle("PRODUCTION");
// entity.setYear(registerReq.getYear());
entity.setGroupTitle(LearnDataType.PRODUCTION.getId());
entity.setDataYear(registerReq.getYear());
entity.setRoundNo(registerReq.getRoundNo() != null ? registerReq.getRoundNo() : 1L);
entity.setMemo(registerReq.getMemo());
entity.setStatus("READY");
entity.setStatus(LearnDataRegister.READY.getId());
entity.setDataType("CREATE");
entity.setTotalItems(0L);
entity.setTotalSize(0L);
entity.setItemCount(0L);
entity.setDeleted(false);
entity.setCreatedDttm(ZonedDateTime.now());
entity.setId1(0L); // 임시값
// entity.setId1(0L); // 임시값
DatasetEntity savedEntity = datasetRepository.save(entity);
// 저장 후 id1을 dataset_uid와 동일하게 업데이트
savedEntity.setId1(savedEntity.getId());
savedEntity = datasetRepository.save(savedEntity);
// savedEntity.setId1(savedEntity.getId());
// savedEntity = datasetRepository.save(savedEntity);
return savedEntity.toDto();
}
@@ -273,4 +281,27 @@ public class DatasetCoreService
double kb = size / 1024.0;
return String.format("%.2f KB", kb);
}
public Page<Basic> searchDatasetObjectList(SearchReq searchReq) {
Page<DatasetObjEntity> entityPage = datasetObjRepository.searchDatasetObjectList(searchReq);
return entityPage.map(DatasetObjEntity::toDto);
}
public UUID deleteDatasetObjByUuid(UUID uuid) {
DatasetObjEntity entity =
datasetObjRepository
.findByUuid(uuid)
.orElseThrow(() -> new NotFoundException("데이터셋 obj를 찾을 수 없습니다. ID: " + uuid));
entity.setDeleted(true);
datasetObjRepository.save(entity);
return entity.getUuid();
}
public List<SelectDataSet> getDatasetSelectM1List(String modelType, String selectType) {
return datasetRepository.getDatasetSelectM1List(modelType, selectType);
}
public List<SelectDataSet> getDatasetSelectM2M3List(String modelType, String selectType) {
return datasetRepository.getDatasetSelectM2M3List(modelType, selectType);
}
}

View File

@@ -9,7 +9,6 @@ import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Map;
import java.util.UUID;
@@ -66,24 +65,6 @@ public class DatasetEntity {
@Column(name = "status", length = 20)
private String status;
@Size(max = 50)
@Column(name = "reg_user_id", length = 50)
private String regUserId;
@ColumnDefault("now()")
@Column(name = "reg_dttm")
private Instant regDttm;
@Column(name = "mod_dttm")
private Instant modDttm;
@Column(name = "id")
private Long id1;
@Size(max = 50)
@Column(name = "created_by", length = 50)
private String createdBy;
@NotNull
@ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
@@ -101,17 +82,9 @@ public class DatasetEntity {
@Column(name = "total_items")
private Long totalItems;
@Size(max = 50)
@Column(name = "updated_by", length = 50)
private String updatedBy;
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm;
@Size(max = 4)
@Column(name = "year", length = 4)
private String year;
@Column(name = "class_counts", columnDefinition = "jsonb")
@JdbcTypeCode(SqlTypes.JSON)
private Map<String, Integer> classCounts;

View File

@@ -0,0 +1,100 @@
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.dataset.dto.DatasetObjDto;
import com.kamco.cd.training.dataset.dto.DatasetObjDto.Basic;
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;
@Getter
@Setter
@Entity
@Table(name = "tb_dataset_obj")
public class DatasetObjEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "obj_id", nullable = false)
private Long objId;
@NotNull
@Column(name = "dataset_uid", nullable = false)
private Long datasetUid;
@Column(name = "target_yyyy")
private Integer targetYyyy;
@Size(max = 255)
@Column(name = "target_class_cd")
private String targetClassCd;
@Column(name = "compare_yyyy")
private Integer compareYyyy;
@Size(max = 255)
@Column(name = "compare_class_cd")
private String compareClassCd;
@Size(max = 255)
@Column(name = "target_path")
private String targetPath;
@Size(max = 255)
@Column(name = "compare_path")
private String comparePath;
@Size(max = 255)
@Column(name = "label_path")
private String labelPath;
@Size(max = 255)
@Column(name = "geojson_path")
private String geojsonPath;
@Size(max = 255)
@Column(name = "map_sheet_num")
private String mapSheetNum;
@ColumnDefault("now()")
@Column(name = "created_dttm")
private ZonedDateTime createdDttm;
@Column(name = "created_uid")
private Long createdUid;
@ColumnDefault("false")
@Column(name = "deleted")
private Boolean deleted;
@Column(name = "uuid")
private UUID uuid;
public Basic toDto() {
return new DatasetObjDto.Basic(
this.objId,
this.datasetUid,
this.targetYyyy,
this.targetClassCd,
this.compareYyyy,
this.compareClassCd,
this.targetPath,
this.comparePath,
this.labelPath,
this.geojsonPath,
this.mapSheetNum,
this.createdDttm,
this.createdUid,
this.deleted,
this.uuid);
}
}

View File

@@ -0,0 +1,7 @@
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.postgres.entity.DatasetObjEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface DatasetObjRepository
extends JpaRepository<DatasetObjEntity, Long>, DatasetObjRepositoryCustom {}

View File

@@ -0,0 +1,14 @@
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.dataset.dto.DatasetObjDto.SearchReq;
import com.kamco.cd.training.postgres.entity.DatasetObjEntity;
import java.util.Optional;
import java.util.UUID;
import org.springframework.data.domain.Page;
public interface DatasetObjRepositoryCustom {
Optional<DatasetObjEntity> findByUuid(UUID id);
Page<DatasetObjEntity> searchDatasetObjectList(SearchReq searchReq);
}

View File

@@ -0,0 +1,97 @@
package com.kamco.cd.training.postgres.repository.dataset;
import static com.kamco.cd.training.postgres.entity.QDatasetEntity.datasetEntity;
import static com.kamco.cd.training.postgres.entity.QDatasetObjEntity.datasetObjEntity;
import com.kamco.cd.training.dataset.dto.DatasetObjDto.SearchReq;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import com.kamco.cd.training.postgres.entity.DatasetObjEntity;
import com.kamco.cd.training.postgres.entity.QDatasetEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityNotFoundException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class DatasetObjRepositoryImpl implements DatasetObjRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QDatasetEntity dataset = datasetEntity;
@Override
public Optional<DatasetObjEntity> findByUuid(UUID id) {
return Optional.ofNullable(
queryFactory
.select(datasetObjEntity)
.from(datasetObjEntity)
.where(datasetObjEntity.uuid.eq(id), datasetObjEntity.deleted.isFalse())
.fetchOne());
}
@Override
public Page<DatasetObjEntity> searchDatasetObjectList(SearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
BooleanBuilder builder = new BooleanBuilder();
if (searchReq.getCompareYyyy() != null) {
builder.and(datasetObjEntity.compareYyyy.eq(searchReq.getCompareYyyy()));
}
if (searchReq.getTargetYyyy() != null) {
builder.and(datasetObjEntity.targetYyyy.eq(searchReq.getTargetYyyy()));
}
if (StringUtils.isNotBlank(searchReq.getCompareClassCd())) {
builder.and(datasetObjEntity.compareClassCd.eq(searchReq.getCompareClassCd()));
}
if (StringUtils.isNotBlank(searchReq.getTargetClassCd())) {
builder.and(datasetObjEntity.targetClassCd.eq(searchReq.getTargetClassCd()));
}
if (StringUtils.isNotBlank(searchReq.getMapSheetNum())) {
builder.and(datasetObjEntity.mapSheetNum.eq(searchReq.getMapSheetNum()));
}
DatasetEntity entity =
queryFactory
.selectFrom(datasetEntity)
.where(datasetEntity.uuid.eq(searchReq.getUuid()))
.fetchOne();
if (Objects.isNull(entity)) {
throw new EntityNotFoundException("DatasetEntity not found for uuid: " + searchReq.getUuid());
}
List<DatasetObjEntity> content =
queryFactory
.selectFrom(datasetObjEntity)
.where(
datasetObjEntity
.deleted
.isFalse()
.and(datasetObjEntity.datasetUid.eq(entity.getId()))
.and(builder))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
// Count 쿼리 별도 실행 (null safe handling)
long total =
Optional.ofNullable(
queryFactory
.select(datasetObjEntity.count())
.from(datasetObjEntity)
.where(datasetObjEntity.deleted.isFalse().and(builder))
.fetchOne())
.orElse(0L);
return new PageImpl<>(content, pageable, total);
}
}

View File

@@ -1,7 +1,9 @@
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.dataset.dto.DatasetDto;
import com.kamco.cd.training.dataset.dto.DatasetDto.SelectDataSet;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.springframework.data.domain.Page;
@@ -10,4 +12,8 @@ public interface DatasetRepositoryCustom {
Page<DatasetEntity> findDatasetList(DatasetDto.SearchReq searchReq);
Optional<DatasetEntity> findByUuid(UUID id);
List<SelectDataSet> getDatasetSelectM1List(String modelType, String selectType);
List<SelectDataSet> getDatasetSelectM2M3List(String modelType, String selectType);
}

View File

@@ -1,9 +1,15 @@
package com.kamco.cd.training.postgres.repository.dataset;
import static com.kamco.cd.training.postgres.entity.QDatasetObjEntity.datasetObjEntity;
import com.kamco.cd.training.dataset.dto.DatasetDto;
import com.kamco.cd.training.dataset.dto.DatasetDto.SelectDataSet;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import com.kamco.cd.training.postgres.entity.QDatasetEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.CaseBuilder;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import java.util.Optional;
@@ -72,4 +78,100 @@ public class DatasetRepositoryImpl implements DatasetRepositoryCustom {
.where(dataset.uuid.eq(id), dataset.deleted.isFalse())
.fetchOne());
}
@Override
public List<SelectDataSet> getDatasetSelectM1List(String modelType, String selectType) {
BooleanBuilder builder = new BooleanBuilder();
if (StringUtils.isNotBlank(selectType) && !"CURRENT".equals(selectType)) {
builder.and(dataset.groupTitle.eq(selectType));
}
return queryFactory
.select(
Projections.constructor(
SelectDataSet.class,
dataset.id,
dataset.uuid,
dataset.groupTitle,
dataset.title,
dataset.roundNo,
dataset.memo,
new CaseBuilder()
.when(datasetObjEntity.targetClassCd.eq("building"))
.then(1)
.otherwise(0)
.sum(),
new CaseBuilder()
.when(datasetObjEntity.targetClassCd.eq("container"))
.then(1)
.otherwise(0)
.sum()))
.from(dataset)
.leftJoin(datasetObjEntity)
.on(dataset.id.eq(datasetObjEntity.datasetUid))
.where(builder) // datasetObjEntity.targetClassCd.in("building", "container").and(
.groupBy(
dataset.id,
dataset.uuid,
dataset.groupTitle,
dataset.title,
dataset.roundNo,
dataset.memo)
.orderBy(dataset.createdDttm.desc())
.fetch();
}
@Override
public List<SelectDataSet> getDatasetSelectM2M3List(String modelType, String selectType) {
BooleanBuilder builder = new BooleanBuilder();
NumberExpression<Long> selectedCnt;
NumberExpression<Long> wasteCnt =
datasetObjEntity.targetClassCd.when("waste").then(1L).otherwise(0L).sum();
NumberExpression<Long> elseCnt =
new CaseBuilder()
.when(datasetObjEntity.targetClassCd.notIn("building", "container", "waste"))
.then(1L)
.otherwise(0L)
.sum();
if (modelType.equals("M2")) {
selectedCnt = wasteCnt;
} else {
selectedCnt = elseCnt;
}
if (StringUtils.isNotBlank(selectType) && !"CURRENT".equals(selectType)) {
builder.and(dataset.groupTitle.eq(selectType));
}
return queryFactory
.select(
Projections.constructor(
SelectDataSet.class,
dataset.id,
dataset.uuid,
dataset.groupTitle,
dataset.title,
dataset.roundNo,
dataset.memo,
selectedCnt.as("cnt")))
.from(dataset)
.leftJoin(datasetObjEntity)
.on(dataset.id.eq(datasetObjEntity.datasetUid))
.where(builder)
.groupBy(
dataset.id,
dataset.uuid,
dataset.groupTitle,
dataset.title,
dataset.roundNo,
dataset.memo)
.orderBy(dataset.createdDttm.desc())
.fetch();
}
}