在 Hibernate 中重用查询

发布于 2024-10-30 17:17:58 字数 710 浏览 0 评论 0原文

我在 Hibernate 中使用 HQL 查询,只是想知道是否可以提高应用程序重用查询的性能。

通常你必须为每个会话创建一个新的查询对象:

Session session;
Query q1 = session.createQuery("select a from Article a where id=:id");
q1.setInteger("id",123);
List result = q1.list();

现在我在 HQL 中有相对复杂的查询,我不想一遍又一遍地解析它们。有没有办法创建查询并在另一个会话中重用 itt?像这样:

Session session;
Query q2 = q1.reattach();
q2.setInteger("id",123);
List result = q2.list();

如果 Hibernate 无论如何都使用准备好的语句,这应该会带来显着的性能提升,特别是与缓存准备好的语句的 ConnectionPool 结合使用。

编辑:通常不需要在 Hibernate 中重用查询,因为无论如何查询计划已经缓存在 QueryPlanCache 类中。命名查询也没有提供任何改进,因为它们仅用于查找查询字符串并且没有与它们关联的计划。

结论:在 Hibernate 中重用查询是没有用的。请务必始终使用参数化查询,因此请保持计划缓存较小。

I use HQL queries in Hibernate, and just wondered, if I could increase the preformance of my app reusing queries.

Usually you have to create a new Query object for each session:

Session session;
Query q1 = session.createQuery("select a from Article a where id=:id");
q1.setInteger("id",123);
List result = q1.list();

Now I have relatively complex queries in HQL, which I don't want to have parsed over and over again. Is there a way to create a query and reuse itt in another session? Like this:

Session session;
Query q2 = q1.reattach();
q2.setInteger("id",123);
List result = q2.list();

If Hibernate uses prepared statements anyway, this should be a notable performance gain, especially in combination with a ConnectionPool that caches prepared statements.

EDIT: Reusing Queries in Hibernate is usually not needed, because the query plan is already cached in the class QueryPlanCache anyway. Named Queries also do not provide any improvement also, because they are just used to lookup the query string and no plan is associated with them.

To conclude: There is no use in reusing Queries in Hibernate. Just be sure to use parametrized queries ALWAYS, so keep the plan caches small.

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

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

发布评论

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

评论(2

少女的英雄梦 2024-11-06 17:17:58

您可以使用“命名查询”:像这样注释您的实体类

@Entity
@NamedQuery(name="Article.findById", query="select a from Article a where id=:id")     
public class Article{ ...

,然后它将在启动时解析一次,每当您想要使用它时,您只需调用:

session.getNamedQuery("Article.findById")
        .setInteger("id",123); 

You may use 'Named Query': Annotate your Entity class like

@Entity
@NamedQuery(name="Article.findById", query="select a from Article a where id=:id")     
public class Article{ ...

and then it will be parsed once at start up, whenever you want using it you simply call:

session.getNamedQuery("Article.findById")
        .setInteger("id",123); 
北笙凉宸 2024-11-06 17:17:58

命名查询为 Kiavash 描述的 执行您所要求的操作,但我怀疑它为您带来任何形式的显着性能提升。

如果您的数据库支持准备好的语句,则无论您是否使用 Hibernate 的命名查询,都会使用准备好的语句。最多就是省去了解析HQL查询的麻烦。命名查询更适合代码重用。

Named Query as described by Kiavash does what you are asking but I doubt that it gives you any kind of significant performance boost.

Prepared statements are used if your database supports them regardless if you are using Hibernate's Named Queries or not. At most you are saving the trouble of parsing HQL query. Named Query is more intended for code reuse.

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