を期待通りには、私はこのようなProduct
モデルオブジェクトを持っている -キャッシュ
class ProductDTO {
int id;
String code;
String description;
//getters and setters go here
}
私はIDまたはコードによって製品を検索し、その説明を返すサービス(以下コード)を書いています。私はSpring 4とehcacheを使用して結果をキャッシュしています。コードによって、ルックアップのためのIDによる検索のために1つずつ - - 彼らはgetProductByCode
とgetProductById
ある
私は2つの方法があります。どちらも文字列として説明を返します。彼らはすべての製品のリストを返すgetAllProducts()
を呼び出すことによってそうする。呼び出し側は、IDまたはコードと一致する製品をリストから検索し、説明を返します。キャッシュ内の説明文字列を保存するには - - キーcode
とid
によって
getAllProducts()
も各製品の@CachePut
と2つのメソッドを呼び出します。
code
またはid
〜getProductByCode
とgetProductById
メソッドに同じ引数が渡された場合、キャッシュは正常に動作します。しかし、別の引数を渡すと、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;
}
}
キャッシングはAOPを使用して実装されます。 AOPはプロキシを使用して適用されるため、オブジェクトに入るメソッド呼び出しにのみ適用されます。内部メソッド呼び出しはプロキシを経由しないので、2つのメソッド呼び出しは基本的に無駄です。 –
ありがとうM.Deinum。この情報は別のポストと一緒に(私は今、そのリンクを失って申し訳ありません)助けました。私は両方のputDescriptionInCache()メソッドを下層(ProductsRepository内)に移動し、getProductByCode()とgetProductById() - @Cacheable( "products")にアノテーションを追加しました。このようにして、最初の呼び出しはgetAllProducts()を経由してデータをキャッシュします。また、私のProductRepositoryには、getDirectionalTextById()メソッドとgetDirectionalTextByCode()メソッドの2つのメソッドがあります。それぞれが説明を取得するSQLを持っています。私はこれらを上の1つの層と同じ名前のメソッドから呼びます。 – lenniekid