如何使用二级缓存将JPA DAO迁移到Spring Data?

时间:2015-05-10 15:46:02

标签: spring jpa caching spring-data spring-data-jpa

我有很多JPA DAO正在寻求迁移到Spring Data JPA。我的一些DAOS设置了二级/查询缓存。

我有一个流程,我只在查询中检索ID,然后使用findByID()查找实体。这样,只有id在不同的查询缓存中相乘,整个实体都在二级缓存中。

示例:

@NamedQuery(name = "SystemUser.findByEmail",
            query = "SELECT u.id FROM SystemUser u WHERE email=:email"),
…

public SystemUser findByEmail(String email) {

    TypedQuery<Long> q = getEntityManager().createNamedQuery("SystemUser.findByEmail", Long.class);
    q.setParameter("email", email);
    q.setHint("org.hibernate.cacheable", true);
    q.setHint("org.hibernate.cacheRegion", "query.systemUser");

    List<Long> res = q.getResultList();

    if (res != null && res.size() > 0) {
        return findById(res.get(0));
    }

    return null;
}

我还有几个findBy… - 方法,所有这些都是这样做的。感觉这是保持缓存内存消耗的好方法。

我对Spring Data JPA业务有点新意,但我看不出如何在这里实现这个目标? @Cacheable注释似乎只处理查询缓存,我会在每个查询缓存中复制实体吗?

有没有办法用Spring Data做到这一点?指针将非常感激。

1 个答案:

答案 0 :(得分:4)

在Spring Data JPA中只需创建一个findByEmail方法,Spring Data JPA将找到您的命名查询或自己创建一个。

public class SystemUserRepository extends CrudRepository<SystemUser, Long> {

    SystemUser findByEmail(String email);
}

应该只需要执行查询和所需的结果。现在使用@QueryHints,您可以添加您现在正在设置的提示。

public class SystemUserRepository extends CrudRepository<SystemUser, Long> {

    @QueryHints(
        @QueryHint(name="org.hibernate.cacheable", value="true"),
        @QueryHint(name="org.hibernate.cacheRegion", value="query.systemUser")        )
    SystemUser findByEmail(String email);
}

结果将被缓存,用户仍将来自二级缓存(如果可用,否则创建)。假设您的实体当然是@Cacheable

可以找到关于2个不同缓存如何协同工作的精彩内容here。关于查询缓存如何工作的小片段。

  

查询缓存在概念上看起来像一个哈希映射,其中密钥由查询文本和参数值组成,该值是与查询匹配的实体ID列表

如果您想要更复杂的逻辑(并且真正实现您所做的优化),您始终可以实施own repository