From 7c053127ddc4cbfdf0aef8778029d087cd11d808 Mon Sep 17 00:00:00 2001 From: Thomas Risberg Date: Mon, 1 Jun 2009 20:40:08 +0000 Subject: [PATCH] added convenience method that takes vararg of objects in the order of the declared parameters (SPR-5696) --- .../jdbc/object/StoredProcedure.java | 32 +++++++++- .../jdbc/object/StoredProcedureTests.java | 58 ++++++++++++++++++- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/StoredProcedure.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/StoredProcedure.java index b070e4baa7..7dcf06b8a6 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/StoredProcedure.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/StoredProcedure.java @@ -17,6 +17,9 @@ package org.springframework.jdbc.object; import java.util.Map; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.List; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; @@ -98,6 +101,31 @@ public abstract class StoredProcedure extends SqlCall { super.declareParameter(param); } + /** + * Execute the stored procedure with the provided parameter values. This is + * a convenience method where the order of the passed in parameter values + * must match the order that the parameters where declared in. + * @param inParams variable number of input parameters. Output parameters should + * not be included in this map. + * It is legal for values to be null, and this will produce the + * correct behavior using a NULL argument to the stored procedure. + * @return map of output params, keyed by name as in parameter declarations. + * Output parameters will appear here, with their values after the + * stored procedure has been called. + */ + public Map execute(Object... inParams) { + Map paramsToUse = new HashMap(); + validateParameters(inParams); + int i = 0; + for (SqlParameter sqlParameter : getDeclaredParameters()) { + if (sqlParameter.isInputValueProvided()) { + if (i < inParams.length) { + paramsToUse.put(sqlParameter.getName(), inParams[i++]); + } + } + } + return getJdbcTemplate().call(newCallableStatementCreator(paramsToUse), getDeclaredParameters()); + } /** * Execute the stored procedure. Subclasses should define a strongly typed @@ -106,7 +134,7 @@ public abstract class StoredProcedure extends SqlCall { * execute methods will often take domain objects as arguments and return values. * Alternatively, they can return void. * @param inParams map of input parameters, keyed by name as in parameter - * declarations. Output parameters need not (but can be) included in this map. + * declarations. Output parameters need not (but can) be included in this map. * It is legal for map entries to be null, and this will produce the * correct behavior using a NULL argument to the stored procedure. * @return map of output params, keyed by name as in parameter declarations. @@ -127,7 +155,7 @@ public abstract class StoredProcedure extends SqlCall { * Subclass execute methods will often take domain objects as arguments and return values. * Alternatively, they can return void. * @param inParamMapper map of input parameters, keyed by name as in parameter - * declarations. Output parameters need not (but can be) included in this map. + * declarations. Output parameters need not (but can) be included in this map. * It is legal for map entries to be null, and this will produce the correct * behavior using a NULL argument to the stored procedure. * @return map of output params, keyed by name as in parameter declarations. diff --git a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/StoredProcedureTests.java b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/StoredProcedureTests.java index 29d4a75187..ddce92f5a3 100644 --- a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/StoredProcedureTests.java +++ b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/StoredProcedureTests.java @@ -113,6 +113,13 @@ public class StoredProcedureTests extends AbstractJdbcTests { assertEquals(4, id); } + private void testAddInvoiceUsingObjectArray(final int amount, final int custid) + throws Exception { + AddInvoiceUsingObjectArray adder = new AddInvoiceUsingObjectArray(mockDataSource); + int id = adder.execute(amount, custid); + assertEquals(5, id); + } + public void testAddInvoices() throws Exception { mockCallable.setObject(1, new Integer(1106), Types.INTEGER); ctrlCallable.setVoidCallable(); @@ -137,8 +144,36 @@ public class StoredProcedureTests extends AbstractJdbcTests { ctrlConnection.setReturnValue(mockCallable); replay(); - testAddInvoice(1106, 3); + + } + + public void testAddInvoicesUsingObjectArray() throws Exception { + mockCallable.setObject(1, new Integer(1106), Types.INTEGER); + ctrlCallable.setVoidCallable(); + mockCallable.setObject(2, new Integer(4), Types.INTEGER); + ctrlCallable.setVoidCallable(); + mockCallable.registerOutParameter(3, Types.INTEGER); + ctrlCallable.setVoidCallable(); + mockCallable.execute(); + ctrlCallable.setReturnValue(false); + mockCallable.getUpdateCount(); + ctrlCallable.setReturnValue(-1); + mockCallable.getObject(3); + ctrlCallable.setReturnValue(new Integer(5)); + if (debugEnabled) { + mockCallable.getWarnings(); + ctrlCallable.setReturnValue(null); + } + mockCallable.close(); + ctrlCallable.setVoidCallable(); + + mockConnection.prepareCall("{call " + AddInvoice.SQL + "(?, ?, ?)}"); + ctrlConnection.setReturnValue(mockCallable); + + replay(); + testAddInvoiceUsingObjectArray(1106, 4); + } public void testAddInvoicesWithinTransaction() throws Exception { @@ -762,6 +797,27 @@ public class StoredProcedureTests extends AbstractJdbcTests { } } + private static class AddInvoiceUsingObjectArray extends StoredProcedure { + + public static final String SQL = "add_invoice"; + + public AddInvoiceUsingObjectArray(DataSource ds) { + setDataSource(ds); + setSql(SQL); + declareParameter(new SqlParameter("amount", Types.INTEGER)); + declareParameter(new SqlParameter("custid", Types.INTEGER)); + declareParameter(new SqlOutParameter("newid", Types.INTEGER)); + compile(); + } + + public int execute(int amount, int custid) { + Map out = execute(new Object[] {amount, custid}); + System.out.println("####### " + out); + Number id = (Number) out.get("newid"); + return id.intValue(); + } + } + private static class NullArg extends StoredProcedure {