Search code examples
javaguavamemoizationsupplier

java: cache database table with 1 hour refresh


I need some cache solution for java. I need to store content of 1 db table with 1 hour eviction then clear all values and populate data from table again.

I was looking into guava cache but it seems it does not provide required api in CacheLoader. Method CacheLoader.load populates only 1 value (so I want populate all values simultaneously) and CacheLoader.loadAll should be triggered by getAll call which is should be avoided in my case.

This is a pseudo code of what I want:

Cache<String, String> cache = CacheBuilder.newBuilder()
    .expireAfterWrite(1, TimeUnit.HOURS)
    .build(new CacheLoader<String, String> {
         public Map<String, String> loadAll()  {
             // some logic for retrieving data from db  
         }
    })

...
String value = cache.get(key)

Possible duplicate of this. But it seems pretty old and doesn't contain desired solution.

Also I have a different use cases, in some of them data should be retrieve from web server or file on file system so I don't want to rely on any database specific approach as hibernate cache or something of the kind.

Thanks!


Solution

  • Have you looked at Guava's Suppliers with memoization? There's support for Supplier memoization with eviction. You can use it to build something like this:

    public class DatabaseDataProvider {
    
     private final Supplier<Map<String, String>> dbDataSupplier;
    
     public DatabaseDataProvider(long duration) {
      final Supplier<Map<String, String>> supplier = () -> loadDbData();
    
      if (duration <= 0) {
       this.dbDataSupplier = supplier; //no caching
      } else {
       this.dbDataSupplier =
        Suppliers.memoizeWithExpiration(supplier, duration, TimeUnit.SECONDS);
      }
    
     }
    
     public Map<String, String> getAllDbData() {
      return dbDataSupplier.get();
     }
    
     private Map<String, String> loadDbData() {
      //DB magick
     }