关于通用方法的Spring MVC @Cacheable注释

时间:2013-06-29 06:11:54

标签: spring hibernate caching spring-mvc annotations

我正在使用Spring MVC和Hibernate

通用方法

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

在控制器中

List<GenCurrencyModel> currencyList=pt.getAllById(GenCurrencyModel.class,1);

问题

我们如何在Generic方法中使用 @Cacheable(“abc”)注释并使用带有通用DAO的spring mvc + hibernate按需销毁缓存

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

@Cacheable("books")
public Book findBook(ISBN isbn) {...}

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

1 个答案:

答案 0 :(得分:4)

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

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

最后一点可以通过始终提供类型信息来解决,例如方法中的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')
)

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

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

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