2017-06-02 7 views
0

ich diesen Code haben,Get Statement von JDBCTemplate

SimpleJdbcCall sql = new SimpleJdbcCall(dataSource).withProcedureName(procName); 
sql.execute(parameters); 

Und ich glaube, dass diese verwendet eine JDBC-Statement unter der Haube. Wie komme ich von hier zu diesem Objekt? (Ich muss die .getWarnings() -Methode für die Anweisung aufrufen).

Mit anderen Worten, wie kann ich SQLWarnings AND benannte Parameter erhalten?

Antwort

1

Es dauerte eine Menge zu graben, aber hier ist, wie Sie SQLWarnings (oder Print-Anweisungen) AND benannte Parameter erhalten können. Ich erweiterte JdbcTemplate und überschrieb die Methode handleWarnings() und übergab diese dann an mein SimpleJdbcCall.

public class JdbcTemplateLoggable extends JdbcTemplate{ 


    List<String> warnings; 

    public JdbcTemplateLoggable(DataSource dataSource){ 
     super(dataSource); 
     warnings = new ArrayList<String>(); 
    } 

    protected void handleWarnings(Statement stmt){ 
     try { 
      SQLWarning warning = stmt.getWarnings(); 
      while(warning != null){ 
       warnings.add(warning.getMessage()); 
       warning = warning.getNextWarning(); 
      } 
     } catch (SQLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    public List<String> getWarnings(){ 
     return warnings; 
    } 
} 

Da ist in meinem Hauptprogramm

JdbcTemplateLoggable template = new JdbcTemplateLoggable(dataSource); 
     SimpleJdbcCall sql = new SimpleJdbcCall(template).withProcedureName(procName); 
     sql.execute(parameters); 
     for(String s : template.getWarnings()){ 
      log.info(s); 
     } 
1

Sie sollten vielleicht JdbcTemplate direkt verwenden, oder Unterklasse für die Verwendung mit Ihrem SimpleJdbcCall (anstelle von DataSource). JdbcTemplate hat eine Methode execute(CallableStatementCreator, CallableStatementCallback), in der ein Callback übergeben werden kann, der das verwendete Statement-Objekt abruft.

Sie können diese Methode überschreiben und den übergebenen Callback mit einem eigenen umbrechen, der die Anweisung zur späteren Verwendung speichert.

public class CustomJdbcTemplate extends JdbcTemplate { 

    private CallableStatement lastStatement; 

    public CustomJdbcTemplate(DataSource dataSource) { 
     super(dataSource); 
    } 

    public CallableStatement getLastStatement() { 
     return lastStatement; 
    } 

    @Override 
    public <T> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action) throws DataAccessException { 
     StoringCallableStatementCallback<T> callback = new StoringCallableStatementCallback<T>(action); 
     try { 
      return super.execute(csc, callback); 
     } 
     finally { 
      this.lastStatement = callback.statement; 
     } 
    } 

    private static class StoringCallableStatementCallback<T> implements CallableStatementCallback<T> { 

     private CallableStatementCallback<T> delegate; 

     private CallableStatement statement; 

     private StoringCallableStatementCallback(CallableStatementCallback<T> delegate) { 
      this.delegate = delegate; 
     } 

     @Override 
     public T doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException { 
      this.statement = cs; 
      return delegate.doInCallableStatement(cs); 
     } 

    } 

} 

Beachten Sie, dass die Aussage wird wahrscheinlich geschlossen werden, wenn Sie es später wieder abrufen, so getWarnings() Fehler verursachen können, auf verwendet JDBC-Treiber abhängig. Vielleicht sollten Sie die Warnungen anstelle der Anweisung selbst speichern.

+0

Hey Dank für diese Lösung. Ich bin Callbacks ein wenig neu, also meine Frage ist, wie werde ich das tatsächlich in meinem Programm nennen? (Und ändert sich das, wenn ich eine NamedJDBCTemplate verwende?) NamedCustomJdbcTemplate.execute (sql, params, <....>) – Steve

+0

Upvoted für die Mühe (und vielleicht funktioniert es auch), aber ich habe eine andere Lösung, die ich momentan – Steve

+0

@Steve Ihre posten Lösung ist ** viel ** besser. –