Java 如何以编程方式将HQL转换为SQL查询(无需日志记录)
我正在执行以下HQL,并且它正在正确执行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
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
解包到Hibernateorg.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)
]