2

我正在使用带有 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();
}

在控制器中

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

问题

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

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

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

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

4

1 回答 1

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')
)

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

这不是一个很大的努力。Spring 默认缓存提供者毕竟只是一张地图。您的实现可以为每种类型使用不同的“子缓存”。

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

于 2013-06-30T09:30:57.317 回答