如何在会话级别启用hibernate查询缓存?

时间:2009-09-16 12:40:03

标签: hibernate session multithreading query-cache session-cache

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

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

由于

3 个答案:

答案 0 :(得分:5)

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

1)Enable query cache

2)专门针对有问题的查询区域并将其标记为可缓存:

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

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

SessionFactory sessionFactory = ...;
sessionFactory.evictQueries("MY_SPECIAL_QUERY");

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

我不知道Hibernate的任何此类功能。

但这似乎是一个非常有限和易于管理的背景。我会尝试这样做是代码。乍一看似乎有各种各样的方式:

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

      

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

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