在 Hibernate 中重用查询
我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用“命名查询”:像这样注释您的实体类
,然后它将在启动时解析一次,每当您想要使用它时,您只需调用:
You may use 'Named Query': Annotate your Entity class like
and then it will be parsed once at start up, whenever you want using it you simply call:
命名查询为 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.