Query jpql = entityManager.createQuery("""
select
YEAR(p.createdOn) as year,
count(p) as postCount
from
Post p
group by
YEAR(p.createdOn)
""", Tuple.class
);
使用Hibernate类型,提取Hibernate生成的SQL查询就这么简单:
String sql = SQLExtractor.from(jpql);
并且,如果我们记录提取的SQL查询:
LOGGER.info("""
The JPQL query: [
{}
]
generates the following SQL query: [
{}
]
""",
jpql.unwrap(org.hibernate.query.Query.class).getQueryString(),
sql
);
我们得到以下输出:
- The JPQL query: [
select
YEAR(p.createdOn) as year,
count(p) as postCount
from
Post p
group by
YEAR(p.createdOn)
]
generates the following SQL query: [
SELECT
extract(YEAR FROM sqlextract0_.created_on) AS col_0_0_,
count(sqlextract0_.id) AS col_1_0_
FROM
post p
GROUP BY
extract(YEAR FROM p.created_on)
]
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<PostComment> criteria = builder.createQuery(PostComment.class);
Root<PostComment> postComment = criteria.from(PostComment.class);
Join<PostComment, Post> post = postComment.join("post");
criteria.where(
builder.like(post.get("title"), "%Java%")
);
criteria.orderBy(
builder.asc(postComment.get("id"))
);
Query criteriaQuery = entityManager.createQuery(criteria);
String sql = SQLExtractor.from(criteriaQuery);
assertNotNull(sql);
LOGGER.info("""
The Criteria API, compiled to this JPQL query: [
{}
]
generates the following SQL query: [
{}
]
""",
jpql.unwrap(org.hibernate.query.Query.class).getQueryString(),
sql
);
当运行上面的测试用例时,我们得到以下SQL查询:
- The Criteria API, compiled to this JPQL query: [
select
pc
from
PostComment as pc
inner join
pc.post as p
where
p.title like :param0
order by
pc.id asc
]
generates the following SQL query: [
SELECT
pc.id AS id1_1_,
pc.post_id AS post_id3_1_,
pc.review AS review2_1_
FROM
post_comment pc
INNER JOIN
post p ON pc.post_id=p.id
WHERE
p.title LIKE ?
ORDER BY
pc.id ASC
]
9条答案
按热度按时间czq61nw11#
对于Eclipselink:您可以通过以下方式提取SQL:
它只在**查询执行后才起作用。
33qvvth12#
JPA规范
虽然没有标准的JPA功能来实现这一目标,但您仍然可以使用JPA提供程序特定的API从JPQL或Criteria API
Query
提取SQL查询。Hyperpersistence 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
Query
解包到Hibernateorg.hibernate.query.Query
接口,该接口提供了getQueryString
方法,我们可以使用该方法记录相关的JPQL查询字符串。从JPA Criteria API Query获取SQL语句
SQLExtractor
不限于JPQL查询。您也可以将其用于Criteria API查询,如以下示例所示:当运行上面的测试用例时,我们得到以下SQL查询:
首先将Criteria API编译为JPQL查询,如
getQueryString()
方法调用所示。中间JPQL查询被进一步转换为SQL查询,该查询由
SQLExtractor
实用程序正确解析。bqjvbblv3#
如果你只想知道你的JPQL或Criteria Query是如何被翻译成数据库的SQL方言的,你可以在 persistence xml 中启用细粒度的日志记录,然后查看日志文件。
属性名称和值取决于您的JPA实现。下面是 persistence.xml 的相关部分的一个例子:
zqry0prt4#
按照Karol的回答-在EclipseLink中执行语句之前可以检索SQL:
要在执行期间/之后检索SQL字符串,最好使用持久性属性而不是代码内:
m3eecexj5#
除了像@Matt Handy提到的那样启用日志记录,还可以在运行时使用eclipselink获取特定查询的SQL字符串,如这里所述。
tjrkku2a6#
使用Hibernate作为提供程序,您可以启用以下属性:
将所有SQL语句写入控制台。这是将日志类别org.hibernate.SQL设置为debug的替代方法。(例如:true|假的)
在日志和控制台中打印SQL。(例如:true|假的)
或者,如上所述,您可以启用日志记录器的调试级别
在执行所有SQL DML语句时记录这些语句
htzpubme7#
如果有一种方法可以从javax.persistence.Query(更准确地说是可能的子类之一)中“提取”JPQL字符串(或者是参数的占位符,或者是参数填充后的最终JPQL),您可能会感兴趣,在这种情况下,根据JPA规范合同,这是不可能的。然而,这在JPA实现中是可能的(例如,NamedQueryImpl可以有#toJPQLString(),您可以通过强制转换访问它),但我对此表示怀疑。即使这是可能的,我也不认为这是一个好的代码执行这样的操作。我建议你找到另一种设计解决方案(为此,你可以指定你有什么样的实际问题)。例如,如果您正在动态构建查询,则可以使用JPA Criteria API,并且沿着“构建”JPA查询,您可以维护反映查询逻辑的内部数据结构。
b5lpy0ml8#
此博客包含说明:http://narcanti.keyboardsamurais.de/hibernate-hql-to-sql-translation.html
s2j5cfk09#
你可以使用p6spy。在以下链接中有其操作说明: