Files
ga-commission-system/ga-common/src/main/java/com/ga/common/upload/LookupCache.java
T
2026-05-12 22:16:27 +09:00

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(); }
}