我有这段代码,
SimpleJdbcCall sql = new SimpleJdbcCall(dataSource).withProcedureName(procName);
sql.execute(parameters);
我相信,它使用了一个JDBC语句。我怎样才能从这里到达那个对象? (我需要在语句中调用.getWarnings()方法)。
换句话说,如何获取SQLWarnings AND 命名参数?
答案 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);
}