What is the correct way to invoke stored procedures using modern day (circa 2012) Spring JDBC Template?
Say, I have a stored procedure that declares both IN
and OUT
parameters, something like this:
mypkg.doSomething(
id OUT int,
name IN String,
date IN Date
)
I have come across CallableStatementCreator
based approaches where we have to explicitly register IN
and OUT
parameters. Consider the following method in JdbcTemplate
class:
public Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters)
Of course, I do know that I can use it like so:
List<SqlParameter> declaredParameters = new ArrayList<SqlParameter>();
declaredParameters.add(new SqlOutParameter("id", Types.INTEGER));
declaredParameters.add(new SqlParameter("name", Types.VARCHAR));
declaredParameters.add(new SqlParameter("date", Types.DATE));
this.jdbcTemplate.call(new CallableStatementCreator() {
@Override
CallableStatement createCallableStatement(Connection con) throws SQLException {
CallableStatement stmnt = con.createCall("{mypkg.doSomething(?, ?, ?)}");
stmnt.registerOutParameter("id", Types.INTEGER);
stmnt.setString("name", "<name>");
stmnt.setDate("date", <date>);
return stmnt;
}
}, declaredParameters);
What is the purpose of declaredParameters
when I am already registering them in my csc
implementation? In other words, why would I need to pass in a csc
when spring can simply do con.prepareCall(sql)
internally? Basically, can't I pass in either one of them instead of both of them?
Or, is there a much better way to call stored procedures (using Spring JDBC Template) than what I have come across so far?
Note: You may find many questions that appear to have a similar title but they are not the same as this one.
There are a number of ways to call stored procedures in Spring.
If you use CallableStatementCreator
to declare parameters, you will be using Java's standard interface of CallableStatement
, i.e register out parameters and set them separately. Using SqlParameter
abstraction will make your code cleaner.
I recommend you looking at SimpleJdbcCall
. It may be used like this:
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName(schema)
.withCatalogName(package)
.withProcedureName(procedure)();
...
jdbcCall.addDeclaredParameter(new SqlParameter(paramName, OracleTypes.NUMBER));
...
jdbcCall.execute(callParams);
For simple procedures you may use jdbcTemplate
's update
method:
jdbcTemplate.update("call SOME_PROC (?, ?)", param1, param2);