java criteria exist_java - 如何从Hibernate Criteria API获取SQL(* not *用于记录) - 堆栈内存溢出...

===============>>#1 票数:40

这是获取SQL的“另一种”方式:

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

===============>>#2 票数:38 已采纳

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

这显然是脆弱的,不安全的,可以打破Hibernate等的变化,但它说明了可以获得SQL:

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中并使用,风险自负。

===============>>#3 票数:10

对于那些使用NHibernate的人来说,这是[ram]代码的一个端口

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

}

===============>>#4 票数:7

如果您使用的是Hibernate 3.6,您可以使用接受的答案中的代码(由Brian Deterling提供)稍作修改:

CriteriaImpl c = (CriteriaImpl) criteria;

SessionImpl s = (SessionImpl) c.getSession();

SessionFactoryImplementor factory = (SessionFactoryImplementor) s.getSessionFactory();

String[] implementors = factory.getImplementors(c.getEntityOrClassName());

LoadQueryInfluencers lqis = new LoadQueryInfluencers();

CriteriaLoader loader = new CriteriaLoader((OuterJoinLoadable) factory.getEntityPersister(implementors[0]), factory, c, implementors[0], lqis);

Field f = OuterJoinLoader.class.getDeclaredField("sql");

f.setAccessible(true);

String sql = (String) f.get(loader);

===============>>#5 票数:4

如果您想获得查询的某些部分,我喜欢这个:

new CriteriaQueryTranslator(

factory,

executableCriteria,

executableCriteria.getEntityOrClassName(),

CriteriaQueryTranslator.ROOT_SQL_ALIAS)

.getWhereCondition();

例如这样的事情:

String where = new CriteriaQueryTranslator(

factory,

executableCriteria,

executableCriteria.getEntityOrClassName(),

CriteriaQueryTranslator.ROOT_SQL_ALIAS)

.getWhereCondition();

String sql = "update my_table this_ set this_.status = 0 where " + where;

===============>>#6 票数:3

这是我使用并为我工作的方法

public static String toSql(Session session, Criteria criteria){

String sql="";

Object[] parameters = null;

try{

CriteriaImpl c = (CriteriaImpl) criteria;

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

sql = (String)f.get(loader);

Field fp = CriteriaLoader.class.getDeclaredField("traslator");

fp.setAccessible(true);

CriteriaQueryTranslator translator = (CriteriaQueryTranslator) fp.get(loader);

parameters = translator.getQueryParameters().getPositionalParameterValues();

}

catch(Exception e){

throw new RuntimeException(e);

}

if (sql !=null){

int fromPosition = sql.indexOf(" from ");

sql = "SELECT * "+ sql.substring(fromPosition);

if (parameters!=null && parameters.length>0){

for (Object val : parameters) {

String value="%";

if(val instanceof Boolean){

value = ((Boolean)val)?"1":"0";

}else if (val instanceof String){

value = "'"+val+"'";

}

sql = sql.replaceFirst("\\?", value);

}

}

}

return sql.replaceAll("left outer join", "\nleft outer join").replace(" and ", "\nand ").replace(" on ", "\non ");

}

===============>>#7 票数:1

对于任何希望在一行中执行此操作的人(例如,在显示/立即窗口,监视表达式或类似的调试会话中),以下将执行此操作并“非常打印”SQL:

new org.hibernate.jdbc.util.BasicFormatterImpl().format((new org.hibernate.loader.criteria.CriteriaJoinWalker((org.hibernate.persister.entity.OuterJoinLoadable)((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory().getEntityPersister(((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory().getImplementors(((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName())[0]),new org.hibernate.loader.criteria.CriteriaQueryTranslator(((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory(),((org.hibernate.impl.CriteriaImpl)crit),((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName(),org.hibernate.loader.criteria.CriteriaQueryTranslator.ROOT_SQL_ALIAS),((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory(),(org.hibernate.impl.CriteriaImpl)crit,((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName(),((org.hibernate.impl.CriteriaImpl)crit).getSession().getEnabledFilters())).getSQLString());

...或者这是一个更容易阅读的版本:

new org.hibernate.jdbc.util.BasicFormatterImpl().format(

(new org.hibernate.loader.criteria.CriteriaJoinWalker(

(org.hibernate.persister.entity.OuterJoinLoadable)

((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory().getEntityPersister(

((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory().getImplementors(

((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName())[0]),

new org.hibernate.loader.criteria.CriteriaQueryTranslator(

((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory(),

((org.hibernate.impl.CriteriaImpl)crit),

((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName(),

org.hibernate.loader.criteria.CriteriaQueryTranslator.ROOT_SQL_ALIAS),

((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory(),

(org.hibernate.impl.CriteriaImpl)crit,

((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName(),

((org.hibernate.impl.CriteriaImpl)crit).getSession().getEnabledFilters()

)

).getSQLString()

);

笔记:

它假定Criteria对象名为crit 。 如果命名不同,请进行搜索和替换 。

它假设Hibernate版本晚于3.3.2.GA但早于4.0,以便使用BasicFormatterImpl来“漂亮地打印”HQL。 如果使用其他版本,请参阅此答案以了解如何修改。 或者也许只是完全删除漂亮的印刷,因为它只是“很高兴” 。

它使用getEnabledFilters而不是getLoadQueryInfluencers()来实现向后兼容,因为后者是在更高版本的Hibernate(3.5 ???)中引入的。

如果参数化参数,则不输出使用的实际参数值。

===============>>#8 票数:0

这个答案基于user3715338的答案(纠正了一个小的拼写错误),并与Michael对Hibernate 3.6的答案相混合 - 基于Brian Deterling接受的答案。 然后我用更多类型替换问号扩展它(对于PostgreSQL):

public static String toSql(Criteria criteria)

{

String sql = "";

Object[] parameters = null;

try

{

CriteriaImpl criteriaImpl = (CriteriaImpl) criteria;

SessionImpl sessionImpl = (SessionImpl) criteriaImpl.getSession();

SessionFactoryImplementor factory = sessionImpl.getSessionFactory();

String[] implementors = factory.getImplementors(criteriaImpl.getEntityOrClassName());

OuterJoinLoadable persister = (OuterJoinLoadable) factory.getEntityPersister(implementors[0]);

LoadQueryInfluencers loadQueryInfluencers = new LoadQueryInfluencers();

CriteriaLoader loader = new CriteriaLoader(persister, factory,

criteriaImpl, implementors[0].toString(), loadQueryInfluencers);

Field f = OuterJoinLoader.class.getDeclaredField("sql");

f.setAccessible(true);

sql = (String) f.get(loader);

Field fp = CriteriaLoader.class.getDeclaredField("translator");

fp.setAccessible(true);

CriteriaQueryTranslator translator = (CriteriaQueryTranslator) fp.get(loader);

parameters = translator.getQueryParameters().getPositionalParameterValues();

}

catch (Exception e)

{

throw new RuntimeException(e);

}

if (sql != null)

{

int fromPosition = sql.indexOf(" from ");

sql = "\nSELECT * " + sql.substring(fromPosition);

if (parameters != null && parameters.length > 0)

{

for (Object val : parameters)

{

String value = "%";

if (val instanceof Boolean)

{

value = ((Boolean) val) ? "1" : "0";

}

else if (val instanceof String)

{

value = "'" + val + "'";

}

else if (val instanceof Number)

{

value = val.toString();

}

else if (val instanceof Class)

{

value = "'" + ((Class) val).getCanonicalName() + "'";

}

else if (val instanceof Date)

{

SimpleDateFormat sdf = new SimpleDateFormat(

"yyyy-MM-dd HH:mm:ss.SSS");

value = "'" + sdf.format((Date) val) + "'";

}

else if (val instanceof Enum)

{

value = "" + ((Enum) val).ordinal();

}

else

{

value = val.toString();

}

sql = sql.replaceFirst("\\?", value);

}

}

}

return sql.replaceAll("left outer join", "\nleft outer join").replaceAll(

" and ", "\nand ").replaceAll(" on ", "\non ").replaceAll("<>",

"!=").replaceAll("", " > ");

}

ask by David Bulté translate from so

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值