在没有hibernate_show_sql = true的情况下将Hql转换为Sql Query

时间:2013-08-22 14:54:23

标签: hibernate hql

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

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

现在我也想在日志中记录后端生成的sql以供支持用户使用,我想利用QueryTranslator请指教我如何为相应的HQL生成sql请告知如何实现这一点。

7 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:4)

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

public void printSorted(PrintStream out) {
        TreeMap<Integer,String> map2 = new TreeMap<Integer,String>();
        for(Map.Entry<String,Integer> entry : concord.entrySet()){
            map2.put(entry.getValue(), entry.getKey());
        }//NavigableMap nmap=treemap.descendingMap();
        for(Map.Entry<Integer,String> entry2 : map2.descendingMap().entrySet()){
            System.out.println(entry2.getValue()+ " " + entry2.getKey());
        }


    }

答案 2 :(得分:1)

您可以使用unwrap方法获取Query。

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

答案 3 :(得分:1)

由于这是一个非常常见的问题,所以此答案基于我在博客上写的this article

休眠类型

从2.9.11版本开始,Hibernate Types开源项目提供了<EntityType Name="Condition"> <Key> <PropertyRef Name="Id"/> </Key> <Property Name="Id" Type="Edm.Int32" Nullable="false"/> <Property Name="Name" Type="Edm.String" Nullable="false" MaxLength="255"/> <Property Name="ActionId" Type="Edm.String" Nullable="false" MaxLength="255"/> <Property Name="Deleted" Type="Edm.Byte" Nullable="false"/> </EntityType> 实用程序,无论您使用什么,该实用程序都可以从任何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)查询:

SQLExtractor

使用Hibernate类型,提取Hibernate生成的SQL查询非常简单:

Query jpql = entityManager.createQuery("""
    select 
       YEAR(p.createdOn) as year, 
       count(p) as postCount 
    from 
       Post p 
    group by 
       YEAR(p.createdOn)
    """, Tuple.class
);

而且,如果我们记录提取的SQL查询:

String sql = SQLExtractor.from(jpql);

我们得到以下输出:

LOGGER.info("""
    The JPQL query: [
        {}
    ]
    generates the following SQL query: [ 
        {}
    ]
    """,
    jpql.unwrap(org.hibernate.query.Query.class).getQueryString(),
    sql
);

请注意,我们已将JPQL(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) ] 展开到休眠Query接口,该接口提供了org.hibernate.query.Query方法,可用于记录相关的JPQL查询字符串。

有关此功能的更多详细信息,请查看this article

答案 4 :(得分:0)

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

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.de/hibernate-hql-to-sql-translation.html

答案 5 :(得分:0)

这可行,其他答案对于现代版本的hibernate也有问题:

String hqlQueryString = query.unwrap(org.hibernate.Query.class).getQueryString(); ASTQueryTranslatorFactory queryTranslatorFactory =新的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); 字符串sqlQueryString = queryTranslator.getSQLString();

答案 6 :(得分: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();