Hibernate是否对HQL查询(在注释中)进行了优化?

时间:2010-04-15 00:42:34

标签: performance hibernate hql named

一位新同事刚刚建议在Hibernate中使用带注释的命名HQL查询(即@NamedQuery),而不是在我们的XxxxRepository类中嵌入HQL。

我想知道的是,除了集中查询外,使用注释是否提供了任何优势?

特别是,是否有一些性能增益,例如,因为查询仅在加载类时解析一次而不是每次执行Repository方法时都会解析?

4 个答案:

答案 0 :(得分:8)

来自Pro EJB 3(Mike Keith)的

  

“......我们建议尽可能使用命名查询。持久性提供程序通常会采取措施将JPQL命名查询预编译为SQL,作为应用程序部署或初始化阶段的一部分。”

尽管本书是关于JPA的,但一般建议适用于Hibernate。但是,由于Hibernate缓存已解析的HQL / JPQL,您可能不会看到很大的性能提升。使用命名查询的另一个好处是,它为您提供了在部署时使用映射文件覆盖查询的选项,而无需重建您的应用程序;如果您需要在生产中调整查询,则非常有用。

答案 1 :(得分:5)

除了任何可能的性能提升之外,我相信另一个优势是,通过使用带注释的HQL查询,您可以保护自己免受SQL注入攻击。

对于Web应用程序,如果查询包含任何用户输入数据,这很重要。

http://en.wikipedia.org/wiki/SQL_injection

答案 2 :(得分:3)

Lars关于SQL注入的评论可能会产生误导,虽然我不认为这是他的意图,我想提供更多的背景,以便评论不会被误解。

命名查询确实是按规范参数化的,命名参数的使用是防止SQL注入的一个步骤。但是,它并不能完全防止SQL注入(请参阅他的链接以获取更多信息)。评论的措辞表明,使用命名查询是防止注入攻击的唯一必要步骤。实际上,普通查询可以(并且应该)进行参数化,并且提供与命名查询完全相同的注入攻击绝缘级别,并且参数化查询只是阻止注入攻击的一些必要步骤之一。

要添加Lars关于webapps的评论,请注意,无论应用程序是否面向外部,或者输入数据是来自用户还是来自其他数据库,都必须擦除数据以防止注入攻击(或者甚至相同的数据库)。

答案 3 :(得分:2)

就我个人而言,我认为性能提升不如在服务器启动期间解析您的hql查询这一事实,如果您的hql查询错误,则为您提供即时消息。

我更倾向于在测试之前而不是在测试期间捕获这些错误。

上次,在测试过程中,由于CaSiNg,我在代码中遇到了一个无效的查询,实际上从未工作过。在服务器启动期间,当使用命名查询时,这将立即变得明显。

当然,我不喜欢将我的HQL与Java代码混合在一起。