我可以从 JPA 查询对象获取 SQL 字符串吗?
我可以知道如何从 JPA 查询中获取 sql 吗?或者说,将 JPA 查询转换为 SQL 字符串?非常感谢!
May I know how can I get the sql from a JPA query? or let's say, convert the JPA query to a SQL string? Thank you very much!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
对于 Eclipselink:您可以通过以下方式提取 SQL:
它仅在执行查询之后后才起作用。
For Eclipselink: you can extract the SQL the following way:
It works only after the query has been executed.
JPA 规范
虽然没有标准 JPA 功能可以实现此目标,但您仍然可以使用 JPA 提供程序特定的 API 从 JPQL 或 Criteria API
查询
中提取 SQL 查询。Hypersistence Utils
Hypersistence Utils 开源项目提供了
SQLExtractor
实用程序它允许您从任何 JPQL 或 Criteria API 查询中获取 SQL 查询,无论您使用的是 Hibernate 6.2、6.1、5.6、 5.5、5.4、5.3、5.2、5.1 或 5.0。从 JPQL 查询获取 SQL 语句
假设我们有以下 JPQL 查询:
使用 Hibernate 类型,提取 Hibernate 生成的 SQL 查询就这么简单:
而且,如果我们记录提取的 SQL 查询:
我们会得到以下输出:
从 JPA Criteria API 查询获取 SQL 语句
SQLExtractor
不限于 JPQL 查询。您也可以将其与 Criteria API 查询一起使用,如以下示例所示:运行上述测试用例时,我们得到以下 SQL 查询:
Criteria API 首先编译为 JPQL 查询,如
所示getQueryString()
方法调用。中间 JPQL 查询进一步转换为 SQL 查询,并由 SQLExtractor 实用程序正确解析。
JPA Specification
While there is not standard JPA functionality to achieve this goal, you can still extract the SQL query from a JPQL or Criteria API
Query
using the JPA provider-specific API.Hypersistence Utils
The Hypersistence Utils open-source project offers the
SQLExtractor
utility that allows you to get the SQL query from any JPQL or Criteria API query, no matter you are using Hibernate 6.2, 6.1, 5.6, 5.5, 5.4, 5.3, 5.2, 5.1, or 5.0.Get the SQL statement from a JPQL Query
Let's assume we have the following JPQL query:
With Hibernate Types, extracting the Hibernate-generated SQL query is as simple as that:
And, if we log the extracted SQL query:
We get the following output:
Get the SQL statement from a JPA Criteria API Query
The
SQLExtractor
is not limited to JPQL queries. You can use it with Criteria API queries as well, as illustrated by the following example:When running the above test case, we get the following SQL query:
The Criteria API is first compiled to a JPQL query, as illustrated by the
getQueryString()
method call.The intermediary JPQL query is further translated to an SQL query, which is properly resolved by the
SQLExtractor
utility.如果您只想知道 JPQL 或条件查询如何转换为数据库的 SQL 方言,您可以在 persistence xml 中启用细粒度日志记录,然后查看日志文件。
属性名称和值取决于您的 JPA 实现。以下是 EclipseLink 的 persistence.xml 相关部分的示例:
If you only want to know how your JPQL or Criteria Query gets translated to the SQL dialect of your database you can enable fine grained logging in the persistence xml and then look into your log files.
The property name and value depends on your JPA implementation. Here is an example of the relevant part of persistence.xml for EclipseLink:
按照 Karol 的回答 - 在 EclipseLink 中执行语句之前可以检索 SQL :
要在执行期间/之后检索 SQL 字符串,最好使用持久性属性而不是代码内来执行此操作:
Following Karol's answer - It is possible to retrieve the SQL before executing the statement in EclipseLink :
To retrieve the SQL String During/After execution it is probably best to do so using persistence properties rather than in-code :
除了像 @Matt Handy 提到的那样启用日志记录之外,还可以在运行时使用 eclipselink 获取特定查询的 SQL 字符串,如所述 此处。
Beside enabling the logging like @Matt Handy mentioned it is also possible to get the SQL String for a specific query with eclipselink at runtime as described here.
使用 Hibernate 作为提供程序,您可以启用以下属性:
将所有 SQL 语句写入控制台。这是设置日志类别 org.hibernate.SQL 进行调试的替代方法。 (例如 true | false)
在日志和控制台中漂亮地打印 SQL。 (例如 true | false)
或者,如上所述,您可以启用记录器的调试级别日志
记录所有执行的 SQL DML 语句
Using Hibernate as a provider you can enable the following properties:
Write all SQL statements to console. This is an alternative to setting the log category org.hibernate.SQL to debug. (e.g. true | false)
Pretty print the SQL in the log and console. (e.g. true | false)
Or, as stated above you can enable logging to the debug level for the logger
Log all SQL DML statements as they are executed
您可能感兴趣是否有一种方法可以从 javax.persistence.Query (更准确地说,它可能是子类之一)中“提取”JPQL 字符串(带有参数的占位符,或者填充参数后的最终 JPQL), - 在这种情况下,根据 JPA 规范合同,这是不可能的。然而,假设这可能通过 JPA 实现实现(例如,NamedQueryImpl 可以有 #toJPQLString(),您可以通过转换访问它),但我对此表示怀疑。
即使有可能,我也不认为这是执行此类操作的好代码。我建议寻找另一种设计解决方案(为此您可以指定您遇到的实际问题类型)。例如,如果您动态构建查询,则可以使用 JPA Criteria API,并且与“构建”JPA 查询一起,您可以维护反映查询逻辑的内部数据结构。
You are probably interested if there's a way to 'extract' JPQL string (either with placeholders for params, or final JPQL after params are filled-in) out of javax.persistence.Query (one of it's possible subclasses to be more precise),- in this case it's not possible according to JPA specification contract. However, this hypothetically might be possible by JPA implementation (e.g., NamedQueryImpl could have #toJPQLString(), which you could access via casting), but I doubt about that.
And even if it's possible I don't think it's a good code performing such manipulations. I would suggest finding another design solutions (and for that you could specify what kind of actual problem do you have). E.g., if you are building your queries dynamically, JPA Criteria API could be used for that, and along with 'building' JPA query, you could maintain your internal data structure reflecting the logic of your query.
此博客包含说明: http://narcanti.keyboardsamurais.de/hibernate- hql-to-sql-translation.html
This blog contains instructions: http://narcanti.keyboardsamurais.de/hibernate-hql-to-sql-translation.html
你可以使用 p6spy。以下链接提供了操作说明:
You could use p6spy. At the following link there are instructions for its operation: