0

次のようなメソッドを持つ PersonDao のようなデータ アクセス オブジェクトが多数あります。

Person findById(String id) {}
List<Person> search(String firstName, LastName, Page) {}
int searchCount(String firstName, LastName) {}

これらのクラスの 1 つを使用してグアバ キャッシュを追加して実験しましたが、これは非常に優れていますが、ボイラープレートがたくさんあります。

findById が最初にキャッシュを参照するようにする例を次に示します。

private final LoadingCache<String, Person> cacheById = CacheBuilder.newBuilder()
  .maximumSize(maxItemsInCache)
  .expireAfterWrite(cacheExpireAfterMinutes, TimeUnit.MINUTES)
  .build(new CacheLoader<String, Person>() {
    public Person load(String key) {
      return findByIdNoCache(key);
  });
//.... and update findById to call the cache ...
@Override
public Person findById(String id) {
  return cacheById.getUnchecked(id);
}

したがって、各メソッドには異なるパラメーターと戻り値の型があるため、メソッドごとに個別の cacheLoader を作成することになります!

オブジェクト型を返し、オブジェクトのマップを受け入れる単一の CacheLoader にすべてを統合しようとしましたが、キャッシュをロードするためにどのメソッドを呼び出すかを判断するために、大きな醜い if/else が発生します。

これらのデータ アクセス オブジェクトにキャッシュを追加するエレガントな方法を見つけるのに苦労しています。何か提案はありますか? たぶん、グアバキャッシュはこのユースケース向けではありませんか?

4

2 に答える 2

5

これを試して。残念ながら、ジェネリックによるコンパイラの警告があります...しかし、何も悪いことが起こらないことがわかっているので、それらを抑制するかもしれません。

public class CacheContainer {

    private static final long maxItemsInCache = 42;
    private static final long cacheExpireAfterMinutes = 42;
    private final Map<String, LoadingCache> caches = Maps.newHashMap();


    public <K, V> V getFromCache(String cacheId, K key, CacheLoader<K, V> loader) throws ExecutionException {
        LoadingCache<K, V> cache = caches.get(cacheId);
        if (cache == null) {
            cache = CacheBuilder.newBuilder().
                     maximumSize(maxItemsInCache).
                     expireAfterWrite(cacheExpireAfterMinutes, TimeUnit.MINUTES).
                     build(loader);
            caches.put(cacheId, cache);
        }
        return cache.get(key);
    }
}

そして、あなたのダオで:

private final CacheContainer cacheContainer = new CacheContainer();


public Person findById(String id) {
    cacheContainer.getFromCache("personById", id, new CacheLoader<String, Person>() {
        @Override
        public Person load(String key) {
          return findByIdNoCache(key);
      });
}

他の方法も同様です。それ以上ボイラープレートを減らすことはできないと思います。

于 2013-10-31T17:08:09.280 に答える