从 JDBCTemplate 获取语句
Get Statement from JDBCTemplate
我有这个代码,
SimpleJdbcCall sql = new SimpleJdbcCall(dataSource).withProcedureName(procName);
sql.execute(parameters);
而且我相信这在幕后使用了 JDBC 语句。我怎样才能从这里到达那个物体? (我需要在语句中调用 .getWarnings() 方法)。
换句话说,我如何获得 SQLWarnings AND 命名参数?
您或许应该直接使用 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 驱动程序。所以也许您应该存储警告而不是语句本身。
这需要大量的挖掘,但这里是您如何获得 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);
}
我有这个代码,
SimpleJdbcCall sql = new SimpleJdbcCall(dataSource).withProcedureName(procName);
sql.execute(parameters);
而且我相信这在幕后使用了 JDBC 语句。我怎样才能从这里到达那个物体? (我需要在语句中调用 .getWarnings() 方法)。
换句话说,我如何获得 SQLWarnings AND 命名参数?
您或许应该直接使用 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 驱动程序。所以也许您应该存储警告而不是语句本身。
这需要大量的挖掘,但这里是您如何获得 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);
}