Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何以编程方式将HQL转换为SQL查询(无需日志记录)_Java_Sql_Hibernate_Hql_Jpql - Fatal编程技术网

Java 如何以编程方式将HQL转换为SQL查询(无需日志记录)

Java 如何以编程方式将HQL转换为SQL查询(无需日志记录),java,sql,hibernate,hql,jpql,Java,Sql,Hibernate,Hql,Jpql,我正在执行以下HQL,并且它正在正确执行 String hql = "FROM Employee"; Query query = session.createQuery(hql); List results = query.list(); 现在,我还想将后端生成的sql记录到支持用户的日志中 我想使用QueryTranslator请告知我如何为相应的HQL生成sql请告知如何实现这一点。您可以使用unwrap方法获取查询 String queryString = query.unwrap(or

我正在执行以下HQL,并且它正在正确执行

String hql = "FROM Employee";
Query query = session.createQuery(hql);
List results = query.list();
现在,我还想将后端生成的sql记录到支持用户的日志中


我想使用QueryTranslator请告知我如何为相应的HQL生成sql请告知如何实现这一点。

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

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

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

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

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

资料来源:

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

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

这是可行的,对于现代版本的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的更高版本中,使用以下代码,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();
休眠类型 从2.9.11版本开始,开源项目提供了
SQLExtractor
实用程序,允许您从任何JPQL或CriteriaAPI查询中获取SQL查询,无论您使用的是Hibernate 5.4、5.3、5.2、5.1、5.0、4.3、4.2或4.1

从JPQL(HQL)查询中获取SQL语句 假设我们有以下JPQL(HQL)查询:

对于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)
]
请注意,我们将JPQL(HQL)
Query
解包到Hibernate
org.Hibernate.Query.Query
接口,该接口提供了
getQueryString
方法,可用于记录关联的JPQL查询字符串


哪个版本的hibernate具有使用展开方法的查询?作为java6持久性api的一部分,这只用于获取HQL查询,而不是SQL查询。幸运的是,这不适用于hibernate 5:(有新的第5个参数
EntityGraphQueryHint
。您可以将null作为第5个参数传递。它应该可以工作。这只返回hql而不是sql;问题是:“现在我还想将后端生成的sql记录在支持用户的日志中”代码最终在“sqlQueryString”中返回hqlQuery的sql等价性变量。不幸的是,没有使用列的别名。createQueryTranslator还需要一个参数:EntityGraphQueryHint。转换后,所有参数如:variable“where替换为”,并且我无法设置参数值。我还尝试设置参数,然后将其转换为SQL,但效果并不理想。注意:我这样做是为了将其作为计数的子查询追加,因为group by中有许多参数,HQL不支持这一点
- 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)
]