Man*_*dan 9 spring caching ehcache spring-3 spring-cache
我正在使用Spring和EhCache
我有以下方法
@Override
@Cacheable(value="products", key="#root.target.PRODUCTS")
public Set<Product> findAll() {
return new LinkedHashSet<>(this.productRepository.findAll());
}
Run Code Online (Sandbox Code Playgroud)
我有其他使用@Cacheable和@CachePut以及@CacheEvict的方法.
现在,假设数据库返回100个产品并且它们被缓存key="#root.target.PRODUCTS"
,然后其他方法将插入 - 更新 - 删除项目到数据库中.因此,通过它缓存的产品key="#root.target.PRODUCTS"
不再相同,例如数据库.
我的意思是,检查以下两种方法,他们能够更新/删除一个项目,同一项目缓存在另一个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);
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否可以通过更新/删除位于缓存中的项目key="#root.target.PRODUCTS"
,如果产品已更新,则为100,如果删除了产品,则为499.
我的观点是,我想避免以下情况:
@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);
}
Run Code Online (Sandbox Code Playgroud)
我不想再打电话给500或499产品缓存到 key="#root.target.PRODUCTS"
这可能吗?怎么样?
提前致谢.
使用缓存抽象缓存集合与底层缓存系统正在执行的操作重复.并且因为这是重复的,事实证明你必须以某种方式在你自己的代码中使用某种重复(该集合的重复键是其明显的表示).因为有重复,你必须以某种方式同步状态
如果你真的需要访问整个集合和单个元素,那么你应该使用最简单的一条快捷方式.首先,您应该确保您的缓存包含所有不明显的元素.实际上远非如此.考虑到你有:
//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);
}
Run Code Online (Sandbox Code Playgroud)
该elements
结果实际上是一个延迟加载地图,以便调用values()
可能会抛出异常.您可能想要循环键或其他东西.
您必须记住,缓存抽象可以简化对底层缓存基础结构的访问,并且绝不会替换它:如果您必须直接使用API,这可能是您在某种程度上必须执行的操作.
现在,如果您认为我们可以改进该领域的缓存抽象,我们可以保留SPR-12036的转换.谢谢!
我认为这样的事情应该有效......实际上,如果“Stéphane Nicoll”回答ofcourse,这只是一个变体,但它可能对某人有用。我写在这里,没有在 IDE 中检查它,但在我的项目中类似的东西。
覆盖 CacheResolver:
@Cacheable(value="products", key="#root.target.PRODUCTS", cacheResolver = "customCacheResolver")
Run Code Online (Sandbox Code Playgroud)实现你自己的缓存解析器,它在你缓存的项目“内部”搜索并在那里完成工作
public class CustomCacheResolver implements CacheResolver{
private static final String CACHE_NAME = "products";
@Autowired(required = true) private CacheManager cacheManager;
@SuppressWarnings("unchecked")
@Override
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> cacheOperationInvocationContext) {
// 1. Take key from query and create new simple key
SimpleKey newKey;
if (cacheOperationInvocationContext.getArgs().length != null) { //optional
newKey = new SimpleKey(args); //It's the key of cached object, which your "@Cachable" search for
} else {
//Schould never be... DEFAULT work with cache if something wrong with arguments
return new ArrayList<>(Arrays.asList(cacheManager.getCache(CACHE_NAME)));
}
// 2. Take cache
EhCacheCache ehCache = (EhCacheCache)cacheManager.getCache(CACHE_NAME); //this one we bringing back
Ehcache cache = (Ehcache)ehCache.getNativeCache(); //and with this we working
// 3. Modify existing Cache if we have it
if (cache.getKeys().contains(newKey) && YouWantToModifyIt) {
Element element = cache.get(key);
if (element != null && !((List<Products>)element.getObjectValue()).isEmpty()) {
List<Products> productsList = (List<Products>)element.getObjectValue();
// ---**--- Modify your "productsList" here as you want. You may now Change single element in this list.
ehCache.put(key, anfragenList); //this method NOT adds cache, but OVERWRITE existing
// 4. Maybe "Create" new cache with this key if we don't have it
} else {
ehCache.put(newKey, YOUR_ELEMENTS);
}
return new ArrayList<>(Arrays.asList(ehCache)); //Bring all back - our "new" or "modified" cache is in there now...
}
Run Code Online (Sandbox Code Playgroud)阅读更多关于 EhCache 的 CRUD:EhCache 代码示例
希望能帮助到你。对不起我的英语:(
归档时间: |
|
查看次数: |
15033 次 |
最近记录: |