1

永続化のために MyBatis を使用している Spring アプリケーションがあります。このアプリケーションでは速度が重要であるため、ehcache を使用しています。MyBatis と Ehcache をセットアップして構成しました。「mybatis」と呼ばれる単一のキャッシュを使用しています。そうしないと、エンティティごとに個別のキャッシュを作成するのがばかげているからです。

これが私のehcache.xmlです。

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd"
         updateCheck="false"
         monitoring="autodetect"
         dynamicConfig="true">

    <diskStore path="java.io.tmpdir" />

    <cache name="mybatis"
           maxBytesLocalHeap="100M"
           maxBytesLocalDisk="1G"
           eternal="false"
           timeToLiveSeconds="0"
           timeToIdleSeconds="0"
           statistics="true"
           overflowToDisk="true"
           memoryStoreEvictionPolicy="LFU">
    </cache>

    <cache name="jersey"
           maxBytesLocalHeap="100M"
           maxBytesLocalDisk="1G"
           eternal="false"
           timeToLiveSeconds="600"
           timeToIdleSeconds="300"
           statistics="true"
           overflowToDisk="true"
           memoryStoreEvictionPolicy="LFU">
    </cache>

</ehcache>

mybatis マッパー インターフェイスのサンプルを次に示します。

import java.util.List;

public interface InstitutionMapper {

    @Cacheable(value = "mybatis")
    List<Institution> getAll();

    @Cacheable(value = "mybatis", key = "id")
    Institution getById(long id);

    @CacheEvict(value = "mybatis")
    void save(Institution institution);

    @CacheEvict(value = "mybatis", key = "id")
    void delete(long id);
}

共有キャッシュを使用しているため、キーをドメイン オブジェクトに対して一意にする方法が必要です。保存または削除の例として、新しい値が UI に表示されるようにキャッシュをクリアする必要があります。ただし、キャッシュ全体をクリアしたくありません。delete が呼び出されてキャッシュが削除されたときに、その ID を持つ機関の mybatis キャッシュ内のエントリのみがクリアされるように、これにアプローチする方法がわかりません。

キーは、ドメイン名 + パラメータのようなものである必要があります。機関+ IDの例として。うまくいけば、それは理にかなっています。

この投稿を見ましたが、クラス名+メソッド+パラメータで行っているようです。

4

1 に答える 1

3

ドメイン モデル全体に​​対して 1 つのリージョンを使用するのは、少し奇妙です (控えめに言っても)。同じキャッシュ内に同様のセマンティクスを持つオブジェクト タイプを収集できると想像できますが、すべてのオブジェクト タイプを収集できるわけではありません。ここで尋ねている質問のほとんどは、適切な境界があれば自然に解決します。

しかし、説明のために、ここにいくつかの考えがあります。

getAll()が必要です。提供しない場合、基本的に@Cacheable引数のない他のメソッドはキャッシュ内の同じキーと競合します。

@Cacheable(value = 'mybatis', key = "'institutions'")
List<Institution> getAll();

@CacheEvictキャッシュされたリストを(メソッドから)クリアするつもりはないのでgetAll()、機関を立ち退かせてもキャッシュされた呼び出しからまだ表示される状況になる可能性がありますgetAll()。複数のレベルで同じものをキャッシュしたい場合は、何かを更新/削除するときに領域全体を削除することをお勧めします。もちろん、エンティティ タイプごとにリージョンがある場合、これはそれほど問題ではありません。

saveメソッドに ID がありません。正確には何を追い出すことになっていますか?IDで既存の機関を見つけなければならないことをどうやって知るのでしょうか?

@CacheEvict(value = "mybatis", key = "#p0.id")
void save(Institution institution);

getAll()(それでも矛盾は解決しませんが)

そこにある唯一のメソッド引数はIDgetByIdであるため、キーは必要ありません。元の「問題」に戻ります。キーに何かプレフィックスを付けたい場合は、全面的に行う必要があります (削除が同じキーに対して機能するように)。1つのケースを忘れる可能性が高すぎるため、SpELではそうしません。

カスタムKeyResolverを実装し、メソッドの戻り値の型に従って一意のプレフィックスを追加できます。

そうは言っても、あなたのサンプルコードはすべて間違っているわけではないので、このトピックに関するドキュメントを確認することをお勧めします

于 2015-07-28T12:55:43.860 に答える