Issue
i am doing a back app using spring boot, i had created an api rest formed by controllers, services and repositories. To the ddbb conection i am using spiring data jdbc.
in some cases i have querys which need pagination, for example the query has 100 results but i only send 10 to front, and on the next request i send the 11-20 results. Now i am using limit and offset in querys but is very slow, my idea is in the first query get 100 results and on the followings request sent results of 10 in 10 but not calling ddbb .
I want to know if is possible on some ways using cache to store this results and in the request obtain the data from the cache not from the ddbb. But how the controllers, services and repositiries are singleton i don' know.
Is possible to use cache in spring api?
Thanks and sorry for my english, is not my native language.
EXAMPLE I have 2 users user1 and user2, both users are 1000 books but the user1's books are differet to user2's books.
In front y show a table with all user1's or user2's books, first i get 100 books from ddbb but only send 10(0-9) to the front, and i put this 100 books in cache, on the second request i dont get books from the ddbb else i get books from the cache and send other 10 books(10-19) on the third request i get also get books from the cache and send another 10 books(20-29) and so on.
But in the 10 request i need send books (100-199) then i need view cache and know that theese books not sotred in cache and i need to do a query which get books (100-199) equal that in the first query and put in cache theese last books(100-199) and remove another books(0-99), i need a memory hashmap that contains <user,list> for example
Solution
Edit
Take a deep breath and realize that the cache is just a map and that the annotation simply automatize the job of filling the map as follow
Key -> the hash of the name of the method + the hash of the arguments
Value -> the value returned from the method itself.
Now, i wrote this simple service, has to 2 operation, 1 that fetch an object using cache if such object is present in cache, the other is to remove such obj from cache.
For this 2 operation we got 2 implementation , 1 using a Map, the other using Cacheable but this 2 implementation behave exactly the same
Hope it helps to clear your mind
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class CacheService {
Map<String,Object> cacheMap = new ConcurrentHashMap<>();
//Simple implementation using ConcurrentHashMap as cache
public Object getObjectUsingMapcache(String key){
if (this.cacheMap.containsKey(key))
return this.cacheMap.get(key);
Object o = getObjectFromExpensiveFunction(key);
this.cacheMap.put(key,o);
return o;
}
//Call this if the object with key key is updated somehow
//And the object for it is no more valid
public void removeObjectFromMapCache(String key){
this.cacheMap.remove(key);
}
@Cacheable(value = "cacheName")
public Object getObjectUsingCacheable(String key){
return getObjectFromExpensiveFunction(key);
}
@CacheEvict(value = "cacheName", key = "#key")
public void removeObjectFromCacheable(String key) {}
//This function is expensive and so we want to cache this function result
public Object getObjectFromExpensiveFunction(String key){
//INCREDIBILY TIME CONSUMING OPERATION HERE...
return new Object();
}
}
Answered By - FrancescoM