使用独立键的番石榴缓存

时间:2015-11-18 20:18:50

标签: java caching guava

使用来自数据库的用户对象时,通常会有一个id和一个用户名,通常用id或用户名搜索用户。

如果我现在想要找到用户并喜欢使用Guava缓存,我必须创建两个缓存。一个是通过id缓存,一个是通过用户名缓存 但两者都指向同一个对象。

是否可以仅使用一个LoadingCache?

我考虑过将用户对象本身用作键LoadingCache<User, User>并在User对象中实现equals和hashcode。
在equals方法中,如果用户名id 相等,则很容易说两个User对象相等。
但是,如何生成适用于此场景的好的hashCode方法呢?

有关于此的任何想法吗?

1 个答案:

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

就是这样。
对此有何评论?