从JDBCTemplate获取Statement

时间:2017-06-02 14:22:28

标签: spring jdbc spring-jdbc

我有这段代码,

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

我相信,它使用了一个JDBC语句。我怎样才能从这里到达那个对象? (我需要在语句中调用.getWarnings()方法)。

换句话说,如何获取SQLWarnings AND 命名参数?

2 个答案:

答案 0 :(得分:1)

您或许应该直接使用JdbcTemplate,或将其子类化以便与SimpleJdbcCall(而非DataSource)一起使用。 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驱动程序。所以也许你应该存储警告而不是声明本身。

答案 1 :(得分:1)

需要大量挖掘,但这里是如何获得SQLWarnings(或Print语句) AND 命名参数。我扩展了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);
        }