使用来自数据库的用户对象时,通常会有一个id和一个用户名,通常用id或用户名搜索用户。
如果我现在想要找到用户并喜欢使用Guava缓存,我必须创建两个缓存。一个是通过id缓存,一个是通过用户名缓存 但两者都指向同一个对象。
是否可以仅使用一个LoadingCache?
我考虑过将用户对象本身用作键LoadingCache<User, User>
并在User对象中实现equals和hashcode。
在equals方法中,如果用户名id 或相等,则很容易说两个User对象相等。
但是,如何生成适用于此场景的好的hashCode方法呢?
有关于此的任何想法吗?
答案 0 :(得分:1)
非常感谢您的答案,特别是来自Guava开发人员的答案。建议的解决方案对我来说很有用,我很懒;)。
因此,如果我从不那么少需要缓存,我决定以这种方式解决它。
final LoadingCache<Serializable, Optional<ITemplate>> templatesById = CacheBuilder.newBuilder()
.maximumSize(MAX_CACHE_SIZE).expireAfterAccess(MAX_CACHE_LIFE_TIME, TimeUnit.MINUTES)
.build(new CacheLoader<Serializable, Optional<ITemplate>>() {
@Override
public Optional<ITemplate> load(final Serializable id) {
final ITemplate template = readInternal(id);
final Optional<ITemplate> optional = Optional.ofNullable(template);
if (template != null) {
templatesByKey.put(template.getKey(), optional);
}
return optional;
}
});
final LoadingCache<String, Optional<ITemplate>> templatesByKey = CacheBuilder.newBuilder()
.maximumSize(MAX_CACHE_SIZE).expireAfterAccess(MAX_CACHE_LIFE_TIME, TimeUnit.MINUTES)
.build(new CacheLoader<String, Optional<ITemplate>>() {
@Override
public Optional<ITemplate> load(final String key) {
final ITemplate template = byKeyInternal(key);
final Optional<ITemplate> optional = Optional.ofNullable(template);
if (template != null) {
templatesById.put(template.getId(), optional);
}
return optional;
}
});
这意味着,我不会因为在两个缓存中有两个模板实例而浪费内存。所以我只是向两个缓存添加一个模板,如果它是从数据库中收到的。
它非常好用,速度很快 唯一的问题是,何时告诉缓存刷新。 在我的场景中,只需要删除或更新。
@Override
@Transactional
public void update(final ITemplate template) {
super.update(new DBTemplate(template));
templatesById.invalidate(template.getId());
templatesByKey.invalidate(template.getKey());
}
就是这样。
对此有何评论?