简体   繁体   中英

How to cache a List<Object> in Java such that the elements in list are cached as a single entry each, using Spring Boot provided caching techniques?

@Query(value = "select  student_rid as row_id, student_name as Name from student_data where student_rid=:Student and visibility=true)", nativeQuery = true)
public List<Map<String, String>> findNameAndRowID(@Param("Student") Long Student);

I want to cache the list output, but when I am trying to cache the output the whole List is cached as a single cache entry, and because of this, I have to evict this whole cache(list) entry all the time when I either insert/delete even a single record into the database, which is not what I want as it does not serves the purpose of caching. So is there a way we can cache the list elements as a single entries such that I can only evict/update the single record at any insert/delete statement.

I am using Spring Boot, Java 8, and Spring tool suite as IDE.

Your use-case seems a little odd since you seem to already only load a single student and only the name of it so I'll try to create a more meaningful example you could build on.

First a disclaimer though: I'm coming from a JavaEE background, haven't used Spring in a while and didn't have a chance to actually test the quickly cobbled together approach I'll describe here so please take it with a grain of salt.

Let's assume you have the following service:

class StudentService {
   @Autowired
   StudentRepository repo;     

   List<Student> loadStudents(someCriteria) {
      return repo.loadStudents(someCriteria);
   }
}

To cache each student you could now introduce a new caching service and call it per student. You might be able to put the method into StudentService but I'm not sure Spring would then be able to inject the necessary handling code (maybe through more advanced AOP and byte-code manipulation).

A simple version could look like this:

class StudentCacheService {
  @CachePut( value = "studentCache", key = "#student.id")
  Student cacheStudent(Student student) {
    return student;
  }
}

class StudentService {
   @Autowired
   StudentRepository repo;     

   @Autowired
   StudentCacheService cacheService;     

   List<Student> loadStudents(someCriteria) {
      List<Student> students = repo.loadStudents(someCriteria);

      //cache each student individually
      students.forEach(s -> cacheService.cacheStudent(s));

      return students;
   }
}

Note that there might be more elegant options like handling it in the cache manager etc. but this should get you started.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM