如何更新/删除已在项目集合中缓存的项目 [英] How update/remove an item already cached within a collection of items

查看:252
本文介绍了如何更新/删除已在项目集合中缓存的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring和EhCache

I am working with Spring and EhCache

我有以下方法

@Override
@Cacheable(value="products", key="#root.target.PRODUCTS")
public Set<Product> findAll() {
    return new LinkedHashSet<>(this.productRepository.findAll());
}

我还有其他使用@Cacheable和@CachePut和@CacheEvict的方法.

I have other methods working with @Cacheable and @CachePut and @CacheEvict.

现在,假设数据库返回了100种产品,并且它们通过key="#root.target.PRODUCTS"进行了缓存,那么其他方法将插入-更新-删除一个项目到数据库中.因此,通过key="#root.target.PRODUCTS"缓存的产品与数据库等不再相同.

Now, imagine the database returns 100 products and they are cached through key="#root.target.PRODUCTS", then other method would insert - update - deleted an item into the database. Therefore the products cached through the key="#root.target.PRODUCTS" are not the same anymore such as the database.

我的意思是,请检查以下两种方法,它们能够更新/删除一个项目,并且相同项目被缓存在另一个key="#root.target.PRODUCTS"

I mean, check the two following two methods, they are able to update/delete an item, and that same item is cached in the other key="#root.target.PRODUCTS"

@Override
@CachePut(value="products", key="#product.id")
public Product update(Product product) {
    return this.productRepository.save(product);
}

@Override
@CacheEvict(value="products", key="#id")
public void delete(Integer id) {
    this.productRepository.delete(id);
}

我想知道是否可以通过key="#root.target.PRODUCTS"更新/删除缓存中的项目,更新后的产品为100,如果删除了产品,则为499.

I want to know if is possible update/delete the item located in the cache through the key="#root.target.PRODUCTS", it would be 100 with the Product updated or 499 if the Product was deleted.

我的意思是,我想避免以下情况:

My point is, I want avoid the following:

@Override
@CachePut(value="products", key="#product.id")
@CacheEvict(value="products", key="#root.target.PRODUCTS")
public Product update(Product product) {
    return this.productRepository.save(product);
}

@Override
@Caching(evict={
        @CacheEvict(value="products", key="#id"),
        @CacheEvict(value="products", key="#root.target.PRODUCTS")
})
public void delete(Integer id) {
    this.productRepository.delete(id);
}

我不想再次调用将500或499种产品缓存到key="#root.target.PRODUCTS"

I don't want call again the 500 or 499 products to be cached into the key="#root.target.PRODUCTS"

这可能吗?怎么样?

谢谢.

推荐答案

使用缓存抽象来缓存集合是底层缓存系统正在执行的操作的重复.而且由于这是重复项,因此您不得不以一种或另一种方式在自己的代码中诉诸某种重复项(集合的重复键很明显就是该重复项).而且由于存在重复,您必须以某种方式同步状态

Caching the collection using the caching abstraction is a duplicate of what the underlying caching system is doing. And because this is a duplicate, it turns out that you have to resort to some kind of duplications in your own code in one way or the other (the duplicate key for the set is the obvious representation of that). And because there is duplication, you have to sync state somehow

如果您确实需要访问整个集合和单个元素,则可能应该使用一条捷径来实现最简单的操作.首先,您应该确保缓存中包含所有显而易见的元素.实际距离还很远.考虑到你有:

If you really need to access to the whole set and individual elements, then you should probably use a shortcut for the easiest leg. First, you should make sure your cache contains all elements which is not something that is obvious. Far from it actually. Considering you have that:

//EhCacheCache cache = (EhCacheCache) cacheManager.getCache("products");


@Override
public Set<Product> findAll() {
    Ehcache nativeCache = cache.getNativeCache();
    Map<Object, Element> elements = nativeCache.getAll(nativeCache.getKeys());
    Set<Product> result = new HashSet<Product>();
    for (Element element : elements.values()) {
        result.add((Product) element.getObjectValue());
    }
    return Collections.unmodifiableSet(result);
}

elements结果实际上是一个延迟加载的映射,因此对values()的调用可能会引发异常.您可能想要遍历键或其他东西.

The elements result is actually a lazy loaded map so a call to values() may throw an exception. You may want to loop over the keys or something.

您必须记住,缓存抽象简化了对底层缓存基础结构的访问,并且绝不替代它:如果您必须直接使用API​​,那么这可能是您在某种程度上要做的.

You have to remember that the caching abstraction eases the access to the underlying caching infrastructure and in no way it replaces it: if you had to use the API directly, this is probably what you would have to do in some sort.

现在,如果您相信我们可以将转换保持在 SPR-12036 上,改善该区域的缓存抽象.谢谢!

Now, we can keep the conversion on SPR-12036 if you believe we can improve the caching abstraction in that area. Thanks!

这篇关于如何更新/删除已在项目集合中缓存的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆