简体   繁体   English

如何以编程方式将 HQL 转换为 SQL 查询(不记录)

[英]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();

Hibernate Types休眠类型

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。

Get the SQL statement from a JPQL (HQL) Query从 JPQL (HQL) 查询中获取 SQL 语句

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 Hibernate org.hibernate.query.Query interface which provided the getQueryString method we can use to log the associated JPQL query string.请注意,我们将 JPQL (HQL) Query解包到 Hibernate org.hibernate.query.Query接口,该接口提供了getQueryString方法,我们可以使用它来记录关联的 JPQL 查询字符串。

您可以使用 unwrap 方法获取查询。

String queryString = query.unwrap(org.hibernate.Query.class).getQueryString();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM