0

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

  • If it slow then identify the cause of the problem. Loading 10 or even 100 records from a relational database should not be slow assuming proper indexing. Additionally, a cache should be transparent and your application should not be concerning itself with managing a cache. – Alan Hay Jul 21 '20 at 15:03
  • Obtain data from db is 46 miliseconds, but after i process this data and this process is 4,3 SECOND then i want store the processed data in cache – roberto fernandez Jul 22 '20 at 06:53

2 Answers2

0

Yes, it's possible to do it. You can use ehcache or Redis[Can be used as distributed among various instances] with a simple configuration. @Pagination will be handle without any specific code.

Thirumal
  • 8,280
  • 11
  • 53
  • 103
  • I have seen this link but this is not solution, i need manage in code the data cache, for example, an user1 has 1000 books, then i want show him the books in table but only sent book of 10 in 10. then in the first front request i get 100 boks froom dataBase, on the second request i get 11-20 books from cache on the 3 eqeuest i get and send 21-30 books ... Then i need know whats data are in cache to know if i can get data from cache or if i get data from ddbb for example in ten front request i need to get data from ddbb. Also the books of User1 are different of the user2 books. For example – roberto fernandez Jul 21 '20 at 13:57
  • `@Caching` will handle the `Pagination` automatically underhood, you don't need to do anything extra. – Thirumal Jul 21 '20 at 14:01
0

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();
  }

}
FrancescoM
  • 1,400
  • 11
  • 16
  • i have reed the guide but thre are some things which i don't know, i dont know how the cache knows how store and remove his data, neither how @Cacheable annotation is pagination. And i want store in cache processed data, not data obtained directly from ddbb – roberto fernandez Jul 22 '20 at 06:51
  • Spring will cache all the data returned by a method annotated with @Cachable. If you want to cache processed data create a service and annotate the method that creates the processed data. Read https://www.baeldung.com/spring-boot-evict-cache about cache eviction or just configure your cache data with an eviction time – FrancescoM Jul 22 '20 at 11:05
  • Okey, but how i know if the cache data are correct, for example: i have in cache (0-99) books, but from the front i recibe a request which needs (120-129) books, how i know thats the data of cache are incorrect and is necessary to do petition to the data base, remove data of cache and store new data Very thanks for you time – roberto fernandez Jul 22 '20 at 17:35
  • I've edited the answer, hoping to clear your mind about it – FrancescoM Jul 23 '20 at 08:55