重用咖啡因缓存键
Reuse caffeine cache key
我已经使用 caffeine
实现了 cache
。我希望它在 1 day
后过期,而且效果很好。问题是,如果我尝试使用修改后的查询(根据参数值进行修改)从 cache
获取数据,我总是会得到相同的结果。只有当我使用相同的参数值(例如相同的日期范围)执行查询时,我才想获得相同的结果。我的理解是我不应该重复使用相同的 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;
}
}
我已经使用 caffeine
实现了 cache
。我希望它在 1 day
后过期,而且效果很好。问题是,如果我尝试使用修改后的查询(根据参数值进行修改)从 cache
获取数据,我总是会得到相同的结果。只有当我使用相同的参数值(例如相同的日期范围)执行查询时,我才想获得相同的结果。我的理解是我不应该重复使用相同的 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;
}
}