2017-03-23 14 views
1

を期待通りには、私はこのようなProductモデルオブジェクトを持っている -キャッシュ

class ProductDTO { 
    int id; 
    String code; 
    String description; 

    //getters and setters go here 
} 

私はIDまたはコードによって製品を検索し、その説明を返すサービス(以下コード)を書いています。私はSpring 4とehcacheを使用して結果をキャッシュしています。コードによって、ルックアップのためのIDによる検索のために1つずつ - - 彼らはgetProductByCodegetProductByIdある

私は2つの方法があります。どちらも文字列として説明を返します。彼らはすべての製品のリストを返すgetAllProducts()を呼び出すことによってそうする。呼び出し側は、IDまたはコードと一致する製品をリストから検索し、説明を返します。キャッシュ内の説明文字列を保存するには - - キーcodeidによって

getAllProducts()も各製品の@CachePutと2つのメソッドを呼び出します。

codeまたはidgetProductByCodegetProductByIdメソッドに同じ引数が渡された場合、キャッシュは正常に動作します。しかし、別の引数を渡すと、getAllProducts()が再び呼び出されます。

希望の動作を達成するには - getAllProducts()に電話するたびにすべての説明がキャッシュに格納され、その後の呼び出しでリポジトリに行くのではなくキャッシュが検索されますか?

public class ProductServiceImpl implements ProductService { 

    @Autowired 
    ProductsRepository ProductRepo; 

    @Override 
    public List<ProductDTO> getAllProducts() { 
     List<ProductDTO> products = ProductRepo.getAllProducts(); 
     for(ProductDTO prodDTO : products) { 
      String desc = prodDTO.getDescription(); 
      String code = prodDTO.getCode(); 
      int id = prodDTO.getId(); 
      putDescriptionInCache(desc, code); 
      putDescriptionInCache(desc, id); 
     } 
     return products; 
    } 

    @CachePut(value = "products", key = "#id") 
    public String putDescriptionInCache(String description, int id){ 
     return description; 
    } 

    @CachePut(value = "products", key = "#code") 
    public String putDescriptionInCache(String description, String code){ 
     return description; 
    } 

    @Override 
    @Cacheable(value="products", key="#id") 
    public String getProductById(Integer id) throws NullPointerException { 
     String dtoDesc = null; 
     List<ProductDTO> products = getAllProducts(); 
     for(ProductDTO currDTO : products) { 
      int currId = currDTO.getId(); 
      if(id.equals(new Integer(currId))) { 
       dtoDesc = currDTO.getDescription(); 
      } 
     } 
     return dtoDesc; 
    } 

    @Override 
    @Cacheable(value="products", key="#code") 
    public String getProductByCode(String code) throws NullPointerException { 
     String dtoDesc = null; 
     List<ProductDTO> products = getAllProducts(); 
     for(ProductDTO currDTO : products) { 
      String currCode = currDTO.getCode(); 
      if(currCode.equals(code)) { 
       dtoDesc = currDTO.getDescription(); 
      } 
     } 
     return dtoDesc; 
    } 
} 
+2

キャッシングはAOPを使用して実装されます。 AOPはプロキシを使用して適用されるため、オブジェクトに入るメソッド呼び出しにのみ適用されます。内部メソッド呼び出しはプロキシを経由しないので、2つのメソッド呼び出しは基本的に無駄です。 –

+0

ありがとうM.Deinum。この情報は別のポストと一緒に(私は今、そのリンクを失って申し訳ありません)助けました。私は両方のputDescriptionInCache()メソッドを下層(ProductsRepository内)に移動し、getProductByCode()とgetProductById() - @Cacheable( "products")にアノテーションを追加しました。このようにして、最初の呼び出しはgetAllProducts()を経由してデータをキャッシュします。また、私のProductRepositoryには、getDirectionalTextById()メソッドとgetDirectionalTextByCode()メソッドの2つのメソッドがあります。それぞれが説明を取得するSQLを持っています。私はこれらを上の1つの層と同じ名前のメソッドから呼びます。 – lenniekid

答えて

1

それはM. Deinumによってコメントしたように、問題は、実行時にアスペクトに変換され、CachePut又はCacheableように、注釈から来ます。そのアプローチの主な制限は、同じクラスからの呼び出しが正しく捕捉されないということです。

あなたが「コメント」セクションで返信したように、注釈付きメソッドを現在のメソッドに注入された別のタイプに移動すると、問題が解決します。

+0

これは@Cacheableのような他のアノテーションにも当てはまりますか? – lenniekid

+0

はい、これをより明確にするために答えを編集しました。もちろん、注釈がメソッド呼び出しを装飾する必要がない場合には、その注釈はそれらには関係しません。 –

関連する問題