如何仅在会话级别启用休眠查询缓存?

发布于 2024-08-05 02:30:17 字数 180 浏览 6 评论 0原文

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

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

谢谢

What if I have a query that gets called multiple times in a single thread, and I just want to cache that query (and its result) for that thread (or for that session since I'm using one session per thread), how can I do that ?

Note: My 2nd level cache is turned on but it's used mostly for session.get(...). But I do not want to use it for my query cache because I only need it to live for the duration of my thread ( / session ).

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

自此以后,行同陌路 2024-08-12 02:30:17

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

1) 启用查询缓存

2) 为相关查询指定一个特定区域并将其标记为可缓存:

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

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

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

The bottom line here is: you can either manually cache your query results or you can ask Hibernate to do it. While it generally makes little sense to restrict your query cache lifetime to that of session, it can be done using the following approach:

1) Enable query cache

2) Dedicate a specific region for query in question and mark it as cacheable:

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

3) Evict your query from cache at the end of the session (if you're REALLY sure that's what you want to do):

SessionFactory sessionFactory = ...;
sessionFactory.evictQueries("MY_SPECIAL_QUERY");
泅人 2024-08-12 02:30:17

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

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

Query caching cannot be applied to the session cache. This makes sense, since generally all operations against a session are done by one piece of code, which should just be able to remember the results itself.

You say you don't want to enable 2nd-level query caching, but what would be the harm in doing so? You'd get your desired results.

停顿的约定 2024-08-12 02:30:17

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

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

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

    <块引用>

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

    假设

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

I don't know of any such feature for Hibernate.

But this seem to be a very limited and manageable context. I would try to do that is the code. Various ways seem possible at first sight:

  • If your code is well known, the complexity is manageable. Suppose you have a code A, that calls codes B and C, both of them need the query. You can run the query once in A, as pass the result to B and C. Maybe you already have a context object that you send to B and C? That would be simple, elegant, meaningfull...
  • Suppose the opposite, that your code is a real mess, and you can't pass a context around. You could have a ThreadLocal variable that contains the result. If not set inside the current thread, call it and store it. Otherwise, just retrieve it.

    Note that, in the second case, you would have to take care of cleaning the ThreadLocal when going out.

  • Between these opposites, solutions are possible, one of them is probably better than others...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文