当前位置: 首页 > 知识库问答 >
问题:

当值为空时,如何避免缓存?

燕翼
2023-03-14

我正在使用Guava缓存热数据。当缓存中不存在数据时,我必须从数据库中获取数据

public final static LoadingCache<ObjectId, User> UID2UCache = CacheBuilder.newBuilder()
        //.maximumSize(2000)
        .weakKeys()
        .weakValues()
        .expireAfterAccess(10, TimeUnit.MINUTES)
        .build(
        new CacheLoader<ObjectId, User>() {
            @Override
            public User load(ObjectId k) throws Exception {
                User u = DataLoader.datastore.find(User.class).field("_id").equal(k).get();
                return u;
            }
        });

我的问题是当数据不存在于数据库中时,我希望它返回null并且不做任何缓存。但Guava保存null与缓存中的关键字,并抛出一个异常,当我得到它:

com.google.common.cache.CacheLoader$InvalidCacheLoadExcION: CacheLoader为shisoft键返回null。

我们如何避免缓存null值?

共有3个答案

狄峰
2023-03-14

面临同样的问题,因为源中缺少值是正常工作流的一部分。没有比自己使用getIfPresentgetput方法编写代码更好的方法了。请参阅下面的方法,其中localCache

private <K, V> V getFromLocalCache(K key, Supplier<V> fallback) {
    @SuppressWarnings("unchecked")
    V s = (V) local.getIfPresent(key);
    if (s != null) {
        return s;
    } else {
        V value = fallback.get();
        if (value != null) {
            local.put(key, value);
        }
        return value;
    }
}

章松
2023-03-14
public final static LoadingCache<ObjectId, Optional<User>> UID2UCache = CacheBuilder.newBuilder()
        ...
        .build(
        new CacheLoader<ObjectId, Optional<User>>() {
            @Override
            public Optional<User> load(ObjectId k) throws Exception {
                return Optional.fromNullable(DataLoader.datastore.find(User.class).field("_id").equal(k).get());
            }
        });

编辑:我认为@Xaerxess的答案更好。

从渊
2023-03-14

如果找不到用户,只需抛出一些异常,并在使用get(key)方法时在客户端代码中捕获它。

new CacheLoader<ObjectId, User>() {
    @Override
    public User load(ObjectId k) throws Exception {
        User u = DataLoader.datastore.find(User.class).field("_id").equal(k).get();
        if (u != null) {
             return u;
        } else {
             throw new UserNotFoundException();
        }
    }
}

CacheLoader.load(K)Javadoc:

Returns:  
  the value associated with key; must not be null  
Throws:  
  Exception - if unable to load the result

回答您对缓存空值的疑问:

返回与此缓存中key关联的值,如果需要,首先加载该值。在加载完成之前,不会修改与此缓存关联的可观察状态。

(fromLoadingCache.get(K)Javadoc)

如果抛出异常,则不会认为加载已完成,因此不会缓存新值。

编辑:

请注意,在Caffeine中,它有点像Guava cache 2.0,并且“使用谷歌Guava启发的API提供内存缓存”,您可以从load方法返回null

 Returns:
   the value associated with key or null if not found

如果可以考虑迁移,则当用户未找到用户时,数据加载程序可以自由返回。

 类似资料:
  • 我有一个有35列的表,其中的条目像day1、day2、day3------一直到day31。我已经用null allow accepted定义了这31列。我正在使用JdbcTemplate方法update(字符串sql,Object…args)插入记录,抛出DataAccessException,该列没有值或为空。。空值插入到表中。。那很好。 但当我更新表时,哪个列已经有一些值,但当前json条目

  • 我有如下所示的JSON 我将文件读成字符串并创建一个JSONObject,如下所示 然而,我认为我可以用try catch将语句括起来 请建议在这种情况下是否有任何合理的理由放一个长的if条件,而不是仅仅try-catch-log然后继续。 您还可以分享使用JSONException在此上下文中是否有任何“优点”吗?

  • 但是,如果camp.start_date为NULL或没有行,那么它将引发异常- ORA-01858:在需要数字的地方发现了一个非数字字符 camp.start_date实际上是一个VARCHAR2,我需要将它转换为日期(是的,我知道它可能应该是一个日期字段,但我没有更改它的选项)。 其中camp.start_date不为null并且to_date(camp.start_date,'mm/dd/yy

  • 将编译为以下内容而不使用装箱: 因此,编译器确实特别对待,但不是在泛型类上下文中。

  • 问题内容: 我需要检查某个值是否为null。如果它不为null,则将一些变量设置为true。这里没有其他声明。这样的条件检查太多了。 有什么方法可以在不检查所有方法返回值的情况下处理此空检查? 我认为直接检查变量并忽略NullpointerException。这是一个好习惯吗? 问题答案: 不,在Java中捕获NPE而不是对您的引用进行空检查通常不是一个好习惯。 如果您愿意,可以使用这种东西: 或

  • 我如何避免在这里过度使用试捕?我如何简化裁员