Spring @Cacheable методы со списками
Я использую последнюю версию Ehcache в своем приложении Spring 4.1.4. Что у меня есть:
class Contact{
int id;
int revision;
}
@Cacheable("contacts")
public List<Contact> getContactList(List<Integer> contactIdList) {
return namedJdbc.queryForList("select * from contact where id in (:idlist)", Collections.singletonMap("idlist", contactIdList));
}
@CachePut(value="contact", key = "id")
public void updateContact(Contact toUpdate) {
jdbctemplate.update("update contact set revision = ? where id = ?", contact.getRevision(), contact.getId());
}
Я хочу добиться того, чтобы контакты сохранялись в кеше, а когда я getContactList
Метод снова, что все контакты которых id
уже кешируются, извлекаются из кеша, а остальные должны быть запрошены как обычно, а затем кешированы. Этот кэш должен затем обновлять кэшированный контактный объект при его обновлении.
Я использую простой Spring JDBC и Ehcache, не JPA и не Hibernate.
1 ответ
Работал у меня. Вот ссылка на мой ответ. /questions/19524109/spring-cachejsr107-argument-listcollection-kak-chast-klyucha/55404654#55404654
TL:DR
@Cacheable(cacheNames = "test", key = "#p0")
public List<String> getTestFunction(List<String> someIds) {
подробнее о моем окружении в ответе.
Не думай, что это возможно. List<Integer>
будет ключом против возвращаемого значения getContactList
будут сохранены в кеше.
Так что, если список идентификаторов, которые вводятся в ваш getContactList
содержит точно такие же идентификаторы, как и в одном из предыдущих вызовов, это будет пропуск кэша и данные будут извлечены из БД. (ПРИМЕЧАНИЕ: два списка считаются равными, если они точно содержат одинаковые элементы и в одинаковом порядке)
Одним из вариантов является изменение вашего метода getContactList(List<Integer> contactIdList)
в getContact(Integer id)
- в этом случае создание кеша может занять некоторое время, но как только контакт для данного идентификатора окажется в кеше, БД не будет использоваться для его повторного извлечения в будущих вызовах.
Хотя это и не элегантно, но другой вариант - сделать кэширование вручную в getContactList
метод.