6

如果我有一个在单个线程中被多次调用的查询,而我只想为该线程(或该会话,因为我每个线程使用一个会话)缓存该查询(及其结果),怎么办?我这样做?

注意:我的二级缓存已打开,但主要用于 session.get(...)。但我不想将它用于我的查询缓存,因为我只需要它在我的线程( / session )期间存在。

谢谢

4

3 回答 3

5

这里的底线是:您可以手动缓存查询结果,也可以让 Hibernate 来做。虽然将查询缓存生命周期限制为会话的生命周期通常没有什么意义,但可以使用以下方法完成:

1)启用查询缓存

2) 为有问题的查询指定一个特定区域并将其标记为可缓存:

Query query = ...;
query.setCacheable(true).setCacheRegion("MY_SPECIAL_QUERY");

3)在会话结束时从缓存中驱逐您的查询(如果您真的确定这是您想要做的):

SessionFactory sessionFactory = ...;
sessionFactory.evictQueries("MY_SPECIAL_QUERY");
于 2009-09-16T15:27:28.923 回答
2

查询缓存不能应用于会话缓存。这是有道理的,因为通常对会话的所有操作都是由一段代码完成的,它应该能够记住结果本身。

您说您不想启用二级查询缓存,但这样做有什么害处?你会得到你想要的结果。

于 2009-09-16T13:32:06.830 回答
0

我不知道 Hibernate 有任何这样的功能。

但这似乎是一个非常有限且易于管理的环境。我会尝试这样做是代码。乍一看似乎有多种方法:

  • 如果您的代码是众所周知的,那么复杂性是可以管理的。假设您有一个代码 A,它调用代码 B 和 C,它们都需要查询。您可以在 A 中运行一次查询,将结果传递给 B 和 C。也许您已经有一个发送给 B 和 C 的上下文对象?那将是简单,优雅,有意义的......
  • 假设相反,你的代码是一团糟,你不能传递上下文。您可以有一个包含结果的 ThreadLocal 变量。如果未在当前线程中设置,则调用它并存储它。否则,只需检索它。

    请注意,在第二种情况下,您必须在外出时清理 ThreadLocal。

  • 在这些对立面之间,解决方案是可能的,其中一个可能比其他更好......

于 2009-09-16T13:26:48.007 回答