[SQL] 최대 절전 모드 기준 API에서 SQL을 얻는 방법 (*하지 * 로깅)
SQL최대 절전 모드 기준 API에서 SQL을 얻는 방법 (*하지 * 로깅)
하이버 네이트의 기준에서 (-생성에-) SQL을 얻을 수있는 쉬운 방법은 무엇입니까?
이상적으로 내가 좋아하는 뭔가를 할 것이다 :
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)
아이디어는 거대한 'MINUS'쿼리의 일환으로 SQL을 사용하는 것 (그리고 MINUS는 최대 절전 모드를 지원하지 않습니다 나는이 동일한 스키마 사이의 차이를 찾을 필요 - - 구조가 동일하지 데이터를)
(BTW 나는 로그 파일에서 SQL을 확인할 수 있습니다 알고)
해결법
-
==============================
1.나는 그것이 HQL, 기준, 또는 네이티브 SQL인지 응용 프로그램의 모든 쿼리 실행을위한 SQL, 매개 변수, 오류, 실행 시간을 잡을 수 있도록 나는 스프링 AOP를 사용하여이 같은 짓을했습니다.
나는 그것이 HQL, 기준, 또는 네이티브 SQL인지 응용 프로그램의 모든 쿼리 실행을위한 SQL, 매개 변수, 오류, 실행 시간을 잡을 수 있도록 나는 스프링 AOP를 사용하여이 같은 짓을했습니다.
이 깨지기 쉬운, 불안 등 최대 절전 모드의 변화와 휴식에 따라 분명하지만, 그것은 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);
자신의 위험에 시도 / 캐치 및 사용 전체 일을 바꿈.
-
==============================
2.여기에 SQL을 얻을 수있는 "또 다른"방법이있다 :
여기에 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();
-
==============================
3.NHibernate에를 사용하는 경우, 이는 [RAM]의 코드 포트는
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.당신은 최대 절전 모드 3.6를 사용하는 경우는 약간의 수정과 (브라이언 Deterling에서 제공) 허용 대답에 코드를 사용할 수 있습니다 :
당신은 최대 절전 모드 3.6를 사용하는 경우는 약간의 수정과 (브라이언 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.쿼리의 단지 일부를 얻으려면 나는이 좋아 :
쿼리의 단지 일부를 얻으려면 나는이 좋아 :
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.여기에 방법 내가 사용하고 나를 위해 일한다
여기에 방법 내가 사용하고 나를 위해 일한다
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.한 줄에서이 작업을 수행하고자하는 사람의 경우 (예를 들어, 디스플레이 / 즉시 창, 디버그 세션에서 시계 발현 또는 유사한에서), 다음이 너무하고 "꽤 인쇄"는 SQL 할 것입니다 :
한 줄에서이 작업을 수행하고자하는 사람의 경우 (예를 들어, 디스플레이 / 즉시 창, 디버그 세션에서 시계 발현 또는 유사한에서), 다음이 너무하고 "꽤 인쇄"는 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() );
노트:
-
==============================
8.이 답변은 user3715338의 답변에 따라 (작은 맞춤법 오류 수정과) 및 최대 절전 모드 3.6 마이클의 대답과 혼합 - 브라이언 Deterling에서 허용 답변에 따라. 나는 다음 몇 가지 더 많은 종류가 questionmarks을 교체하는 (PostgreSQL을위한)를 확장 :
이 답변은 user3715338의 답변에 따라 (작은 맞춤법 오류 수정과) 및 최대 절전 모드 3.6 마이클의 대답과 혼합 - 브라이언 Deterling에서 허용 답변에 따라. 나는 다음 몇 가지 더 많은 종류가 questionmarks을 교체하는 (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("<", " < ").replaceAll(">", " > "); }
from https://stackoverflow.com/questions/554481/how-to-get-sql-from-hibernate-criteria-api-not-for-logging by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 어떻게 테이블에서 가장 큰 ID가 전체 행을 선택합니까? (0) | 2020.03.26 |
---|---|
[SQL] 어떻게 오라클 SQL Developer에서 변수를 사용합니까? (0) | 2020.03.26 |
[SQL] MySQL의 쿼리 문자열이 포함되어 (0) | 2020.03.26 |
[SQL] 어떻게 PDO 데이터베이스 쿼리를 디버깅하는 방법? (0) | 2020.03.26 |
[SQL] SQL Server 2005는 어떻게 고유 제한 조건을 만들기? (0) | 2020.03.26 |