카페인
을 사용하여 캐시
를 구현했습니다. 1 day
후에 만료되기를 원하며 정상적으로 작동합니다. 문제는 수정 된 쿼리 (매개 변수 값으로 수정 됨)를 사용하여 캐시
에서 데이터를 가져 오려고하면 항상 동일한 결과를 얻는다는 것입니다. 동일한 매개 변수 값 (예 : 동일한 날짜 범위)으로 쿼리를 실행 한 경우에만 동일한 결과를 얻고 싶습니다. 내 이해는 동일한 cache-key
를 재사용해서는 안된다는 것입니다.하지만 어떻게하지 않는지 잘 모르겠습니다.이것이 구현입니다.
@Service
public class SomeServiceImpl implements SomeService {
private static final String CACHE_KEY = "some-key";
private Cache<String, List<SomeVO>> someCache;
public RecentHighestSlotWinsServiceImpl() {
someCache= Caffeine.newBuilder().maximumSize(100).expireAfterWrite(1, TimeUnit.DAYS).build();
}
@Override
public List<SomeVO> checkCacheForData(Instant startDate, Instant endDate) {
List<SomeVO> someList= someCache.getIfPresent(CACHE_KEY);
if (someList!= null) {
return someList;
} else {
log.info("Loading from DB ");
List<SomeVO> templateResult= getData(startDate, endDate);
if (templateResult.isSuccessAndNotNull()) {
someCache.put(CACHE_KEY, Objects.requireNonNull(templateResult.getData()));
}
return templateResult;
}
}
이를 처리하는 몇 가지 방법 :
- @Louis Wasserman이 언급했듯이 다음과 같이하십시오.
import java.time.Instant;
import java.util.Objects;
public class CacheKey {
private Instant startDate;
private Instant endDate;
public CacheKey() {
}
public CacheKey(Instant startDate, Instant endDate) {
this.startDate = startDate;
this.endDate = endDate;
}
public Instant getStartDate() {
return startDate;
}
public void setStartDate(Instant startDate) {
this.startDate = startDate;
}
public Instant getEndDate() {
return endDate;
}
public void setEndDate(Instant endDate) {
this.endDate = endDate;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
CacheKey cacheKey = (CacheKey) o;
return Objects.equals(startDate, cacheKey.startDate) &&
Objects.equals(endDate, cacheKey.endDate);
}
@Override
public int hashCode() {
return Objects.hash(startDate, endDate);
}
}
귀하의 방법 checkCacheForData 에서 다음을 사용하십시오.
@Service
public class SomeServiceImpl implements SomeService {
private Cache<CacheKey, List<SomeVO>> someCache;
public RecentHighestSlotWinsServiceImpl() {
someCache= Caffeine.newBuilder().maximumSize(100).expireAfterWrite(1, TimeUnit.DAYS).build();
}
@Override
public List<SomeVO> checkCacheForData(Instant startDate, Instant endDate) {
List<SomeVO> someList= someCache.getIfPresent(new CacheKey(startDate,endDate));
if (someList!= null) {
return someList;
} else {
log.info("Loading from DB ");
List<SomeVO> templateResult= getData(startDate, endDate);
if (templateResult.isSuccessAndNotNull()) {
someCache.put(new CacheKey(startDate,endDate), Objects.requireNonNull(templateResult.getData()));
}
return templateResult;
}
}
- 별도의 객체를 갖는 대신 시작 날짜와 종료 날짜의 문자열 표현을 연결하여 캐시 키로 사용할 수 있습니다.
@Service
public class SomeServiceImpl implements SomeService {
private Cache<String, List<SomeVO>> someCache;
public RecentHighestSlotWinsServiceImpl() {
someCache= Caffeine.newBuilder().maximumSize(100).expireAfterWrite(1, TimeUnit.DAYS).build();
}
@Override
public List<SomeVO> checkCacheForData(Instant startDate, Instant endDate) {
String cacheKey = startDate.toString() + endDate.toString();
List<SomeVO> someList= someCache.getIfPresent(cacheKey);
if (someList!= null) {
return someList;
} else {
log.info("Loading from DB ");
List<SomeVO> templateResult= getData(startDate, endDate);
if (templateResult.isSuccessAndNotNull()) {
someCache.put(cacheKey, Objects.requireNonNull(templateResult.getData()));
}
return templateResult;
}
}