我正在执行下面的HQL,而且执行得很正确。
String hql = "FROM Employee";
Query query = session.createQuery(hql);
List results = query.list();
现在,我还想把在后台生成的sql记录在日志中,供支持用户使用。
我想利用QueryTranslator请教如何才能生成相应HQL的sql请教如何实现。
你可以使用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();
我相信你想要的是前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();
我在网上找到了下一个解决方案。
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。
你可以通过使用unwrap方法把Query弄出来。
String queryString = query.unwrap(org.hibernate.Query.class).getQueryString();
这个可行,其他答案对于现代版本的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()。
在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版本开始, 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)查询。
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
到Hibernateorg.hibernate.query.Query
的接口,提供了getQueryString
方法,我们可以用来记录相关的JPQL查询字符串。有关此功能的更多细节,请查看 本文.