2014-07-24 3 views
6

항목 컬렉션에서 캐시하는 방법에는 다음과 같은 방법업데이트/제거 항목은 이미 내가 봄으로 Ehcache</p> <p>함께 일하고

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

나는 @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); 
} 

가능하면 내가 알고 싶은에 캐시됩니다 캐시에있는 항목을 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); 
} 

나는 key="#root.target.PRODUCTS"

에 캐시 다시 500 개 또는 499 제품 호출하지 않을 수 있나요 이렇게 :

내 요점은 다음과 같은 피하려면, 무엇입니까? 방법?

미리 감사드립니다.

답변

0

쉬운 방법은 없지만 cache decorator을 제공하면 Ehcache 캐시 기능을 무시할 수 있습니다. 대부분 EhcahceDecoratorAdapter을 사용하여 EhCacheCache 삽입 및 제거 방법에서 사용하는 기능을 향상시키고 자 할 것입니다.

5

캐싱 추상화를 사용하여 컬렉션을 캐싱하는 것은 기본 캐싱 시스템이 수행하는 것과 중복됩니다. 그리고 이것이 중복이기 때문에, 당신은 어떤 방식 으로든 자신의 코드에서 어떤 종류의 복제물에 의지해야한다는 것이 밝혀졌습니다 (세트의 중복 키는 그것의 명백한 표현입니다). 중복이 있으므로 어떤 식 으로든 상태를 동기화해야합니다.

전체 세트와 개별 요소에 실제로 액세스해야하는 경우 가장 쉬운 다리에 대한 바로 가기를 사용해야합니다. 먼저, 캐시에 확실한 것이 아닌 모든 요소가 캐시에 포함되어 있는지 확인해야합니다. 실제로 그것에서 멀리.

//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()에 대한 호출이 예외를 던질 수있는 게으른로드 맵 : 고려 당신은 것을 가지고있다. 열쇠 등을 반복 할 수 있습니다.

캐싱 추상화가 기본 캐싱 인프라에 대한 액세스를 용이하게하고 결코 그것을 대체하지 않는다는 것을 기억해야합니다. API를 직접 사용해야하는 경우 일종의 일일 것입니다.

이제 해당 영역의 캐싱 추상화를 향상시킬 수 있다고 생각되면 SPR-12036에 대한 변환을 유지할 수 있습니다. 감사!

+0

감사합니다. Stephane, 나는 JIRA를 통해 대화를 나눌 것입니다. –

1

나는 이걸 어떻게 작동시키는 지 생각해 ... 사실 "Stéphane Nicoll"의 대답은 오르간에 유용 할 수 있지만 실제로는 변이 일뿐입니다. 나는 바로 여기에 쓰고 IDE에서는 확인하지 않았지만, 내 프로젝트에서는 비슷한 것이 작동한다.

  1. 무시 CacheResolver :

    @Cacheable(value="products", key="#root.target.PRODUCTS", cacheResolver = "customCacheResolver") 
    
  2. 더 읽기

    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... 
    } 
    

거기에 일을 "내부는"당신이 항목을 캐시 검색 자신의 캐시 해결을 구현하고 할 EhCache의 CRUD에 대해서 : EhCache code samples

희망이 도움이됩니다. 그리고 내 영어로 유감스럽게 생각합니다. (