如何将HQL转换为SQL查询(不需要记录)的程序。

问题描述 投票:14回答:7

我正在执行下面的HQL,而且执行得很正确。

String hql = "FROM Employee";
Query query = session.createQuery(hql);
List results = query.list();

现在,我还想把在后台生成的sql记录在日志中,供支持用户使用。

我想利用QueryTranslator请教如何才能生成相应HQL的sql请教如何实现。

java sql hibernate hql jpql
7个回答
6
投票

你可以使用hibernate 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();

4
投票

我相信你想要的是前2个答案的组合

  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();

1
投票

我在网上找到了下一个解决方案。

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(); 

资料来源:http:/narcanti.keyboardsamurais.dehibernate-hql-to-sql-translation: http:/narcanti.keyboardsamurais.dehibernate-hql-to-sql-translation.html。


0
投票

你可以通过使用unwrap方法把Query弄出来。

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

0
投票

这个可行,其他答案对于现代版本的hibernate来说有问题。

String hqlQueryString = query.unwrap(org.hibernate.Query.class).getQueryString();ASTQueryTranslatorFactory queryTranslatorFactory = new ASTQueryTranslatorFactory();SessionImplementor hibernateSession = entityManager.unwrap(SessionImplementor.class);QueryTranslator queryTranslator = queryTranslatorFactory() 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()。


0
投票

在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();

0
投票

由于这是一个很常见的问题,所以这个答案是根据 本文 我在我的博客上写道。

Hibernate类型

从2.9.11版本开始, Hibernate类型 开源项目提供了 SQLExtractor 实用程序,允许你从任何JPQL或Criteria API查询中获取SQL查询,无论你使用的是Hibernate 5.4、5.3、5.2、5.1、5.0、4.3、4.2或4.1。

从JPQL(HQL)查询中获取SQL语句。

假设我们有以下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
);

有了Hibernate Types,提取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)
]

请注意,我们解开了JPQL(HQL)的包装 Query 到Hibernate org.hibernate.query.Query 的接口,提供了 getQueryString 方法,我们可以用来记录相关的JPQL查询字符串。

有关此功能的更多细节,请查看 本文.

© www.soinside.com 2019 - 2024. All rights reserved.