2017-06-02 21 views
0

私はこのコードを持っているから、JDBCTemplate

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

をステートメントを取得し、私はボンネットの下に、これはJDBC文を使用していることを信じています。どうすればここからそのオブジェクトにアクセスできますか? (私は文の上で.getWarnings()メソッドを呼び出す必要があります)。

つまり、SQLWarnings という名前のパラメータはどのように取得できますか?

答えて

1

これは多大な掘り出しがありましたが、ここではSQLWarnings(またはPrintステートメント)という名前のパラメーターを取得できます。私はJdbcTemplateを拡張し、handleWarnings()メソッドをオーバーライドし、それを私の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; 
    } 
} 

その後、私のメインプログラムでは、このソリューションのための

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

おそらくJdbcTemplateを直接使用するか、SimpleJdbcCallDataSourceの代わりに)で使用するためにサブクラス化する必要があります。 JdbcTemplateにはメソッドexecute(CallableStatementCreator, CallableStatementCallback)があり、コールバックを渡して、使用されているStatementオブジェクトを取得できます。

このメソッドをオーバーライドし、渡されたコールバックを後で使用できるようにストアする独自のものでラップすることができます。

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

    } 

} 

あなたが後でそれを取得するとき文がおそらくそうgetWarnings()が使用するJDBCドライバに応じて、エラーが発生する可能性があり、閉鎖されることに注意してください。したがって、ステートメント自体の代わりに警告を保存する必要があります。

+0

ちょっと感謝。私はコールバックに少し新しくなったので、私の質問は、私が実際に私のプログラムでこれをどのように呼び出すのでしょうか? (NamedJDBCTemplateを使用している場合はこれが変わりますか?)namedCustomJdbcTemplate.execute(sql、params、<....>) – Steve

+0

Upvoted Up(努力しているかもしれませんが)、私はすぐに投稿する別の解決策を考え出しました。 – Steve

+0

@Steveソリューションは**多く**良いです。 –