首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何从Hibernate Criteria API获取SQL (*非*用于日志记录)

如何从Hibernate Criteria API获取SQL (*非*用于日志记录)
EN

Stack Overflow用户
提问于 2009-02-16 20:41:30
回答 7查看 113.1K关注 0票数 76

有没有办法从Hibernate Criteria获取(要生成的) SQL?

理想情况下,我应该有这样的东西:

代码语言:javascript
复制
Criteria criteria = session.createCriteria(Operator.class);

... build up the criteria ...
... and then do something like ...

String sql = criteria.toSql()

(But this of course does not exist)

我们的想法是使用SQL作为一个巨大的‘减号’查询的一部分(我需要找出两个相同的模式之间的区别--在结构上相同,而不是在数据上--而减号不被Hibernate支持)

(顺便说一句,我知道我可以从日志文件中检查SQL )

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-02-17 00:52:11

我使用Spring AOP做了类似的事情,这样我就可以获取应用程序中运行的任何查询的sql、参数、错误和执行时间,无论它是HQL、Criteria还是原生SQL。

这显然是脆弱的,不安全的,容易受到Hibernate等变化的影响,但它说明了获得SQL是可能的:

代码语言:javascript
复制
CriteriaImpl c = (CriteriaImpl)query;
SessionImpl s = (SessionImpl)c.getSession();
SessionFactoryImplementor factory = (SessionFactoryImplementor)s.getSessionFactory();
String[] implementors = factory.getImplementors( c.getEntityOrClassName() );
CriteriaLoader loader = new CriteriaLoader((OuterJoinLoadable)factory.getEntityPersister(implementors[0]),
    factory, c, implementors[0], s.getEnabledFilters());
Field f = OuterJoinLoader.class.getDeclaredField("sql");
f.setAccessible(true);
String sql = (String)f.get(loader);

将整个东西包装在try/catch中,使用风险自负。

票数 41
EN

Stack Overflow用户

发布于 2010-10-08 16:28:37

下面是获取SQL的“另一种”方法:

代码语言:javascript
复制
CriteriaImpl criteriaImpl = (CriteriaImpl)criteria;
SessionImplementor session = criteriaImpl.getSession();
SessionFactoryImplementor factory = session.getFactory();
CriteriaQueryTranslator translator=new CriteriaQueryTranslator(factory,criteriaImpl,criteriaImpl.getEntityOrClassName(),CriteriaQueryTranslator.ROOT_SQL_ALIAS);
String[] implementors = factory.getImplementors( criteriaImpl.getEntityOrClassName() );

CriteriaJoinWalker walker = new CriteriaJoinWalker((OuterJoinLoadable)factory.getEntityPersister(implementors[0]), 
                        translator,
                        factory, 
                        criteriaImpl, 
                        criteriaImpl.getEntityOrClassName(), 
                        session.getLoadQueryInfluencers()   );

String sql=walker.getSQLString();
票数 46
EN

Stack Overflow用户

发布于 2010-11-12 23:15:40

对于那些使用NHibernate的人来说,这是ram代码的一个移植

代码语言:javascript
复制
public static string GenerateSQL(ICriteria criteria)
    {
        NHibernate.Impl.CriteriaImpl criteriaImpl = (NHibernate.Impl.CriteriaImpl)criteria;
        NHibernate.Engine.ISessionImplementor session = criteriaImpl.Session;
        NHibernate.Engine.ISessionFactoryImplementor factory = session.Factory;

        NHibernate.Loader.Criteria.CriteriaQueryTranslator translator = 
            new NHibernate.Loader.Criteria.CriteriaQueryTranslator(
                factory, 
                criteriaImpl, 
                criteriaImpl.EntityOrClassName, 
                NHibernate.Loader.Criteria.CriteriaQueryTranslator.RootSqlAlias);

        String[] implementors = factory.GetImplementors(criteriaImpl.EntityOrClassName);

        NHibernate.Loader.Criteria.CriteriaJoinWalker walker = new NHibernate.Loader.Criteria.CriteriaJoinWalker(
            (NHibernate.Persister.Entity.IOuterJoinLoadable)factory.GetEntityPersister(implementors[0]),
                                translator,
                                factory,
                                criteriaImpl,
                                criteriaImpl.EntityOrClassName,
                                session.EnabledFilters);

        return walker.SqlString.ToString();
    }
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/554481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档