2014-05-09 3 views
4

디버깅을 위해 jdbi sql api가 정확히 처리 한 sql 쿼리를 알고 싶습니다. 내 인터페이스 클래스는JDBI sql api에서 @SqlQuery 주석을 인쇄하는 방법

public inteface myinteface{ 
    @SqlQuery("select :c1 from tablename where cond = :cd") 
    String returnMeValue(@Bind("c1") String c1, @Bind("cd") Integer cd); 
} 

다음 나중에 내가 실제로 SQL 쿼리에가는 것을보고 싶어, 그래서 내가 대답을 기대 받고 있지 않다 String result = myinterfaceclassobject.returnMeValue("Name",1);

으로 다른 클래스에서 호출됩니다. 그렇다면 최종 처리 쿼리를 가져 오는 방법은 무엇입니까?

+0

같은 질문이 있습니다. 그것을하는 방법을 찾아 냈는가? – froderik

답변

5

SqlCustomizer를 작성하여 sql을 기록 할 수 있습니다.

import org.skife.jdbi.v2.StatementContext; 
import org.skife.jdbi.v2.sqlobject.SqlStatementCustomizer; 
import org.skife.jdbi.v2.sqlobject.SqlStatementCustomizerFactory; 
import org.skife.jdbi.v2.sqlobject.SqlStatementCustomizingAnnotation; 
import org.skife.jdbi.v2.tweak.StatementCustomizer; 

import java.lang.annotation.*; 
import java.lang.reflect.Method; 
import java.sql.PreparedStatement; 
import java.sql.SQLException; 

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
@SqlStatementCustomizingAnnotation(LogSqlFactory.Factory.class) 
public @interface LogSqlFactory { 

    static class Factory implements SqlStatementCustomizerFactory { 

     @Override 
     public SqlStatementCustomizer createForMethod(Annotation annotation, Class sqlObjectType, Method method) { 
      return null; 
     } 

     @Override 
     public SqlStatementCustomizer createForType(Annotation annotation, Class sqlObjectType) { 
      return q -> q.addStatementCustomizer(new StatementCustomizer() { 
       @Override 
       public void beforeExecution(PreparedStatement stmt, StatementContext ctx) throws SQLException { 
        System.out.println(stmt.toString()); 
       } 

       @Override 
       public void afterExecution(PreparedStatement stmt, StatementContext ctx) throws SQLException { } 

       @Override 
       public void cleanup(StatementContext ctx) throws SQLException { } 
      }); 
     } 

     @Override 
     public SqlStatementCustomizer createForParameter(Annotation annotation, Class sqlObjectType, Method method, Object arg) { 
      return null; 
     } 
    } 

} 

그냥이 주석을 포함 SQLObject의에서 이것을 사용합니다. 로깅, 다음 beforeExecution 방법에 대한 사용자 정의 로거를 사용하는 경우 귀하의 경우에는이 같은이 주석,

@LogSqlFactory 
public inteface myinteface{ 
@SqlQuery("select :c1 from tablename where cond = :cd") 
    String returnMeValue(@Bind("c1") String c1, @Bind("cd") Integer cd); 
} 

를 사용합니다.

+0

나는 이것을 시도했지만 작동하지 않았다. 전제 조건이 있습니까? –

0

log4jdbc와 같은 것을 사용하는 것이 훨씬 쉽습니다. Manikandan의 방법을 사용하면 코드가 상당히 느려집니다. 을 반환 보장 할 수 없습니다)

@Override 
    public SqlStatementCustomizer createForType(Annotation annotation, final Class sqlObjectType) { 

    return new SqlStatementCustomizer() { 
     @Override 
     public void apply(SQLStatement sqlStatement) throws SQLException { 
      sqlStatement.addStatementCustomizer(new StatementCustomizer() { 
       @Override 
       public void beforeExecution(PreparedStatement stmt, StatementContext ctx) throws SQLException { 
       System.out.println(stmt.toString()); 
       } 

       @Override 
       public void afterExecution(PreparedStatement stmt, StatementContext ctx) throws SQLException { 
       } 

       @Override 
       public void cleanup(StatementContext ctx) throws SQLException { 
       } 
      }); 
     } 
    }; 

    } 

그러나 stmt.toString (: 당신은 여전히 ​​람다를 지원하지 않습니다 IT와 프로젝트 언어 수준을 사용하려는 경우

그러나, 다음과 같은 수정을 사용할 수 있습니다 SQL 문은 구현에 따라 다릅니다. SQLite에서는 작동하지 않습니다.