2012-12-26 22 views
5

Tôi đang sử dụng bộ đệm cache trừu tượng cho các đối tượng bộ nhớ cache trong lớp dịch vụ. này là tốt cho các hoạt động đơn giản get/đặt như sau:Cách trả về số lượng mục nhập bằng cách sử dụng bộ nhớ đệm mùa xuân trừu tượng

static private final String cacheName = "messages"; 

@CacheEvict(value=cacheName, key="#message.id") 
public void deleteMessage(Message message) { 
... 
} 

@Cacheable(value=cacheName, key="#id") 
public Message findMessage(Long id) { 
... 
} 

@CachePut(value=cacheName, key="#message.id") 
public void saveMessage(Message message) { 
... 
} 

@CachePut(value=cacheName, key="#message.id") 
public Message updateMessage(Message message) { 
... 
} 

Tuy nhiên, những gì chú thích tôi sẽ sử dụng cho các phương pháp sau đây:

public long countAllMessages() { 
... 
} 

Vì tất cả các đối tượng sẽ nằm trong bộ nhớ cache, nên có một cách để có được câu trả lời từ bộ nhớ cache và không phải đi đến tầng kho lưu trữ.

Ngoài ra, bộ nhớ cache đang được áp dụng vào phương pháp sau đây:

@Cacheable(cacheName) 
public List<Message> findAllMessages() { 
... 
} 

tôi có thể làm cho phương pháp đếm gọi tất cả phương pháp như thế này:

public long countAllMessages() { 
    return findAllMessages().size(); 
} 

Nhưng điều này sẽ không có hiệu quả trong trường hợp bộ nhớ cache bị tắt, khi cuộc gọi sau đó sẽ tải tất cả các bản ghi từ db thay vì thực hiện SELECT COUNT (*) ...

Trả lời

9

Tóm tắt bộ đệm Spring hiện không được ovide một cách trực tiếp để truy cập số liệu thống kê về bộ đệm ẩn. Ví dụ, không có cách nào trực tiếp để có được kích thước của tất cả các cache, các khóa của các đối tượng được lưu trữ, vv Đó là một mức trừu tượng cao hơn thế. Tuy nhiên, bạn có thể truy cập vào các lớp bộ nhớ cache cơ bản thông qua phương thức Cache#getNativeCache(). Việc lấy một thể hiện của Cache từ lớp CacheManager sẽ cho phép bạn truy cập vào phương thức này. Giả sử bạn biết các kiểu cơ bản của các thể hiện Cache được quản lý bởi CacheManager, bạn có thể đưa chúng vào các kiểu thích hợp và truy cập vào các phương thức trợ giúp trên mỗi (giả sử có bất kỳ).

Ví dụ: nếu lưu trữ bộ nhớ cache bên dưới là EHCache, bạn có thể lấy một phiên bản của Cache có tên là "tin nhắn" bằng cách gọi CacheManager#getCache("messages"). Sau đó, bạn có thể kiểm tra loại và truyền loại thành net.sf.ehcache.Ehcache, từ đó bạn có thể gọi các phương thức trợ giúp thống kê khác nhau (ví dụ: getStatistics()).

Dưới đây là một ví dụ về trải qua tất cả các bộ nhớ cache do CacheManager quản lý, kiểm tra xem chúng có thuộc loại net.sf.ehcache.Ehcache và sau đó nhận được số liệu thống kê của chúng hay không.

public class EhCacheStatistics { 
    private CacheManager cacheManager; 

    @Inject 
    public void setCacheManager(CacheManager cacheManager) { 
    this.cacheManager = cacheManager; 
    } 

    public long getTotalEhCacheSize() { 
    long totalSize = 0l; 
    for (String cacheName : cacheManager.getCacheNames()) { 
     Cache cache = cacheManager.getCache(cacheName); 
     Object nativeCache = cache.getNativeCache(); 
     if (nativeCache instanceof net.sf.ehcache.Ehcache) { 
     net.sf.ehcache.Ehcache ehCache = (net.sf.ehcache.Ehcache) nativeCache; 
     totalSize += ehCache.getStatistics().getObjectCount(); 
     } 
    } 
    return totalSize; 
    } 
} 
+0

Và làm cách nào để đảm bảo rằng lần đầu tiên countAllMessages() được gọi, nó không nhấn bộ nhớ cache? – Solubris

+0

Thay vì gọi phiên bản countAllMessages(), bạn sẽ gọi getTotalEhCacheSize() hoặc thay thế mã từ getTotalEhCacheSize() thành countAllMessages(). Nếu bạn cần số đếm thực tế từ cơ sở dữ liệu (hoặc bất kỳ phần cuối nào), bạn sẽ cần một phương thức chuyên dụng để thực hiện điều đó, bạn có thể chú thích bằng chú thích @Cacheable (nếu bạn muốn). Nếu bạn muốn nó làm mới bất cứ lúc nào, hãy gỡ bỏ bộ nhớ cache của phương thức khi bạn gọi bất kỳ phương thức cập nhật nào khác hoặc định kỳ gỡ bỏ nó theo cách thủ công, ví dụ như thông qua một công việc nền. –

Các vấn đề liên quan