61 lines
2.6 KiB
Java
61 lines
2.6 KiB
Java
package com.ga.common.upload;
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* LOOKUP 변환 규칙용 캐시.
|
|
* 70만건 업로드 시 행마다 DB 조회를 피하기 위해, 시작 전에 참조 테이블 전체를 Map으로 로드.
|
|
*
|
|
* - preload(columns): 매핑 규칙에 LOOKUP이 있으면 해당 테이블을 한번에 캐시
|
|
* - lookup(table, sourceField, value, targetField): O(1) 조회
|
|
*
|
|
* Note: 이 캐시는 요청 단위 — 매 업로드마다 새로 만들고 끝나면 GC 대상.
|
|
* UploadService 내부에서 new LookupCache(uploadMapper) 로 인스턴스화.
|
|
*/
|
|
@Slf4j
|
|
@RequiredArgsConstructor
|
|
public class LookupCache {
|
|
|
|
private final UploadMapper uploadMapper;
|
|
private final Map<String, Map<String, Object>> caches = new HashMap<>();
|
|
|
|
public void preload(List<UploadTemplateColumnVO> columns) {
|
|
columns.stream()
|
|
.filter(c -> "LOOKUP".equalsIgnoreCase(c.getTransformRule()))
|
|
.filter(c -> c.getLookupTable() != null && c.getLookupSourceField() != null)
|
|
.map(c -> c.getLookupTable() + "|" + c.getLookupSourceField() + "|" + c.getLookupTargetField())
|
|
.distinct()
|
|
.forEach(key -> {
|
|
String[] p = key.split("\\|");
|
|
String table = p[0], src = p[1], tgt = p[2];
|
|
if (!UploadWhitelist.isAllowedLookupTable(table)) {
|
|
throw new IllegalArgumentException("허용되지 않은 LOOKUP 테이블: " + table);
|
|
}
|
|
List<Map<String, Object>> rows = uploadMapper.selectLookupAll(table, src, tgt);
|
|
Map<String, Object> map = new HashMap<>(rows.size());
|
|
for (Map<String, Object> row : rows) {
|
|
Object srcVal = row.get("source_value");
|
|
Object tgtVal = row.get("target_value");
|
|
if (srcVal != null) map.put(srcVal.toString(), tgtVal);
|
|
}
|
|
caches.put(key, map);
|
|
log.info("LookupCache loaded: {} = {} rows", key, map.size());
|
|
});
|
|
}
|
|
|
|
public Object lookup(String table, String sourceField, String value, String targetField) {
|
|
if (value == null) return null;
|
|
Map<String, Object> cache = caches.get(table + "|" + sourceField + "|" + targetField);
|
|
if (cache == null) return null;
|
|
return cache.get(value);
|
|
}
|
|
|
|
public int size() { return caches.size(); }
|
|
}
|