通用方法上的Spring MVC @Cacheable批注

Sha*_*oor 2 spring caching annotations hibernate spring-mvc

我在Hibernate中使用Spring MVC

通用方法

    // getAllById
@SuppressWarnings("unchecked")
public <T> List<T> getAllById(Class<T> entityClass, long id)
        throws DataAccessException {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(entityClass)
            .add(Restrictions.eq("id", id));

    return criteria.list();
}
Run Code Online (Sandbox Code Playgroud)

在控制器中

List<GenCurrencyModel> currencyList=pt.getAllById(GenCurrencyModel.class,1);
Run Code Online (Sandbox Code Playgroud)

我们如何在泛型方法中使用@Cacheable(“ abc”)批注以及如何使用带有常规DAO的spring mvc + hibernate按需销毁缓存

根据spring doc中的示例,它在简单方法上指定注释!

@Cacheable("books")
public Book findBook(ISBN isbn) {...}
Run Code Online (Sandbox Code Playgroud)

我实际上需要,当Id传递给泛型方法时,它应该首先在缓存中查找,并且我还应按需销毁缓存!

a b*_*ver 5

首先考虑一下使用泛型的含义:

  • 您不知道将来会使用哪种类型。您也不知道缓存名称。
  • 您(可能)没有类型信息,因此没有机会选择特定的缓存。

最后一点可以通过始终提供类型信息来解决,就像entityClass您的方法一样。

解决方案1:一个缓存

使用一个缓存并根据类型生成密钥。 @Cacheable(value="myCache", key="#entityClass.name + #id")

解决方案2:使用@Caching

虽然可以将表达式用作键,但不能将其用作缓存名称。@Caching允许您使用多个@Cachable注释,每个注释都有另一个缓存名称。

@Caching (
@Cacheable(value="books", key="#id", condition="#entityClass.name == 'Book'"),
@Cacheable(value="students", key="#id", condition="#entityClass.name == 'Student')
)
Run Code Online (Sandbox Code Playgroud)

解决方案3:编写自己的缓存提供程序

这不是一件容易的事。Spring默认的缓存提供程序毕竟只是一个映射。您的实现可以为每种类型使用不同的“子缓存”。

清除缓存更加困难。解决方案1和3仅具有一个缓存。您不能只清除“书”,而不能清除“学生”。解决方案2具有该选项,但是您必须提供所有可能的缓存和类型。您可以使用解决方案3并直接使用缓存,而不必使用@CacheEvict