[英]How to convert HQL to SQL Query programmatically (without logging)
I am executing the following HQL and it is executing properly我正在执行以下 HQL 并且它正在正确执行
String hql = "FROM Employee";
Query query = session.createQuery(hql);
List results = query.list();
Now, I also want to log the sql generated at the backend in logs for support users.现在,我还想将后端生成的 sql 记录到支持用户的日志中。
I want to make use of QueryTranslator please advise how can I generate the sql for the corresponding HQL please advise how to achieve this.我想使用 QueryTranslator 请告知如何为相应的 HQL 生成 sql 请告知如何实现这一点。
You can use hibernate QueryTranslator:您可以使用休眠 QueryTranslator:
String hqlQueryString = hqlQuery.getQueryString();
ASTQueryTranslatorFactory queryTranslatorFactory = new ASTQueryTranslatorFactory();
SessionImplementor hibernateSession = entityManager.unwrap(SessionImplementor.class);
QueryTranslator queryTranslator = queryTranslatorFactory.createQueryTranslator("", hqlQueryString, java.util.Collections.EMPTY_MAP, hibernateSession.getFactory());
queryTranslator.compile(java.util.Collections.EMPTY_MAP, false);
String sqlQueryString = queryTranslator.getSQLString();
I believe you want a combination of the top 2 answers我相信你想要前两个答案的组合
String hqlQueryString = query.unwrap(org.hibernate.Query.class).getQueryString();
ASTQueryTranslatorFactory queryTranslatorFactory = new ASTQueryTranslatorFactory();
SessionImplementor hibernateSession = em.unwrap(SessionImplementor.class);
QueryTranslator queryTranslator = queryTranslatorFactory.createQueryTranslator("", hqlQueryString, java.util.Collections.EMPTY_MAP, hibernateSession.getFactory());
queryTranslator.compile(java.util.Collections.EMPTY_MAP, false);
String sqlQueryString = queryTranslator.getSQLString();
This is also possible with TypedQuery in later versions of Hibernate using the following code这也可以使用以下代码在更高版本的 Hibernate 中使用 TypedQuery
String hqlQueryString=typedQuery.unwrap(org.hibernate.query.Query.class).getQueryString();
ASTQueryTranslatorFactory queryTranslatorFactory = new ASTQueryTranslatorFactory();
SessionImplementor hibernateSession = entityManager.unwrap(SessionImplementor.class);
QueryTranslator queryTranslator = queryTranslatorFactory.createQueryTranslator("", hqlQueryString, java.util.Collections.EMPTY_MAP, hibernateSession.getFactory(), null);
queryTranslator.compile(java.util.Collections.EMPTY_MAP, false);
String sqlQueryString = queryTranslator.getSQLString();
I found next solution on the web:我在网上找到了下一个解决方案:
QueryTranslatorFactory translatorFactory = new ASTQueryTranslatorFactory();
SessionFactoryImplementor factory = (SessionFactoryImplementor) getSessionFactory();
QueryTranslator translator = translatorFactory.
createQueryTranslator(hqlQueryText, hqlQueryText, Collections.EMPTY_MAP, factory);
translator.compile(Collections.EMPTY_MAP, false);
translator.getSQLString();
Source: http://narcanti.keyboardsamurais.de/hibernate-hql-to-sql-translation.html来源: http : //narcanti.keyboardsamurais.de/hibernate-hql-to-sql-translation.html
This works, other answers have a problem for modern versions of hibernate:这是有效的,其他答案对于现代版本的休眠有问题:
String hqlQueryString = query.unwrap(org.hibernate.Query.class).getQueryString();
ASTQueryTranslatorFactory queryTranslatorFactory = new ASTQueryTranslatorFactory();
SessionImplementor hibernateSession = entityManager.unwrap(SessionImplementor.class);
QueryTranslator queryTranslator = queryTranslatorFactory.createQueryTranslator("", hqlQueryString, java.util.Collections.EMPTY_MAP, hibernateSession.getFactory(), null);
queryTranslator.compile(java.util.Collections.EMPTY_MAP, false);
String sqlQueryString = queryTranslator.getSQLString();
Starting with the 2.9.11 version, the Hibernate Types 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 5.4, 5.3, 5.2, 5.1, 5.0, 4.3, 4.2, or 4.1.从 2.9.11 版本开始, Hibernate Types开源项目提供了
SQLExtractor
实用程序,它允许您从任何 JPQL 或 Criteria API 查询中获取 SQL 查询,无论您使用的是 Hibernate SQLExtractor
、4.3、4.2 或 4.1。
Let's assume we have the following JPQL (HQL) query:假设我们有以下 JPQL (HQL) 查询:
Query jpql = entityManager.createQuery("""
select
YEAR(p.createdOn) as year,
count(p) as postCount
from
Post p
group by
YEAR(p.createdOn)
""", Tuple.class
);
With Hibernate Types, extracting the Hibernate-generated SQL query is as simple as that:使用 Hibernate Types,提取 Hibernate 生成的 SQL 查询就这么简单:
String sql = SQLExtractor.from(jpql);
And, if we log the extracted SQL query:而且,如果我们记录提取的 SQL 查询:
LOGGER.info("""
The JPQL query: [
{}
]
generates the following SQL query: [
{}
]
""",
jpql.unwrap(org.hibernate.query.Query.class).getQueryString(),
sql
);
We get the following output:我们得到以下输出:
- 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)
]
Notice that we unwrapped the JPQL (HQL)
Query
to the Hibernateorg.hibernate.query.Query
interface which provided thegetQueryString
method we can use to log the associated JPQL query string.请注意,我们将 JPQL (HQL)
Query
解包到 Hibernateorg.hibernate.query.Query
接口,该接口提供了getQueryString
方法,我们可以使用它来记录关联的 JPQL 查询字符串。
您可以使用 unwrap 方法获取查询。
String queryString = query.unwrap(org.hibernate.Query.class).getQueryString();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.