1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.jdbc.object;
  17. import java.util.Map;
  18. import javax.sql.DataSource;
  19. import org.springframework.dao.DataAccessException;
  20. import org.springframework.dao.InvalidDataAccessApiUsageException;
  21. import org.springframework.jdbc.core.JdbcTemplate;
  22. import org.springframework.jdbc.core.ParameterMapper;
  23. import org.springframework.jdbc.core.SqlParameter;
  24. /**
  25. * Superclass for object abstractions of RDBMS stored procedures.
  26. * This class is abstract and its execute methods are protected, preventing use other than through
  27. * a subclass that offers tighter typing.
  28. *
  29. * <p>The inherited <code>sql</code> property is the name of the stored procedure in the RDBMS.
  30. * Note that JDBC 3.0 introduces named parameters, although the other features provided
  31. * by this class are still necessary in JDBC 3.0.
  32. *
  33. * @author Rod Johnson
  34. * @author Thomas Risberg
  35. * @version $Id: StoredProcedure.java,v 1.12 2004/05/29 21:20:23 jhoeller Exp $
  36. */
  37. public abstract class StoredProcedure extends SqlCall {
  38. /**
  39. * Allow use as a bean.
  40. */
  41. protected StoredProcedure() {
  42. }
  43. /**
  44. * Create a new object wrapper for a stored procedure.
  45. * @param ds DataSource to use throughout the lifetime
  46. * of this object to obtain connections
  47. * @param name name of the stored procedure in the database
  48. */
  49. protected StoredProcedure(DataSource ds, String name) {
  50. setDataSource(ds);
  51. setSql(name);
  52. }
  53. /**
  54. * Create a new object wrapper for a stored procedure.
  55. * @param jdbcTemplate JdbcTemplate which wraps DataSource
  56. * @param name name of the stored procedure in the database
  57. */
  58. protected StoredProcedure(JdbcTemplate jdbcTemplate, String name) {
  59. setJdbcTemplate(jdbcTemplate);
  60. setSql(name);
  61. }
  62. /**
  63. * Declare a parameter. Overridden method.
  64. * <b>Note: Calls to declareParameter must be made in the same order as
  65. * they appear in the database's stored procedure parameter list.</b>
  66. * Names are purely used to help mapping.
  67. * @param param parameter object
  68. */
  69. public void declareParameter(SqlParameter param) throws InvalidDataAccessApiUsageException {
  70. if (param.getName() == null) {
  71. throw new InvalidDataAccessApiUsageException("Parameters to stored procedures must have names as well as types");
  72. }
  73. super.declareParameter(param);
  74. }
  75. /**
  76. * Execute the stored procedure. Subclasses should define a strongly typed
  77. * execute method (with a meaningful name) that invokes this method, populating
  78. * the input map and extracting typed values from the output map. Subclass
  79. * execute methods will often take domain objects as arguments and return values.
  80. * Alternatively, they can return void.
  81. * @param inParams map of input parameters, keyed by name as in parameter
  82. * declarations. Output parameters need not (but can be) included in this map.
  83. * It is legal for map entries to be null, and this will produce the correct
  84. * behavior using a NULL argument to the stored procedure.
  85. * @return map of output params, keyed by name as in parameter declarations.
  86. * Output parameters will appear here, with their values after the
  87. * stored procedure has been called.
  88. */
  89. public Map execute(final Map inParams) throws DataAccessException {
  90. validateParameters(inParams.values().toArray());
  91. return getJdbcTemplate().call(newCallableStatementCreator(inParams), getDeclaredParameters());
  92. }
  93. /**
  94. * Execute the stored procedure. Subclasses should define a strongly typed
  95. * execute method (with a meaningful name) that invokes this method, passing in
  96. * a ParameterMapper that will populate the input map. This allows mapping database
  97. * specific features since the ParameterMapper has access to the Connection object.
  98. * The execute method is also responsible for extracting typed values from the output map.
  99. * Subclass execute methods will often take domain objects as arguments and return values.
  100. * Alternatively, they can return void.
  101. * @param inParamMapper map of input parameters, keyed by name as in parameter
  102. * declarations. Output parameters need not (but can be) included in this map.
  103. * It is legal for map entries to be null, and this will produce the correct
  104. * behavior using a NULL argument to the stored procedure.
  105. * @return map of output params, keyed by name as in parameter declarations.
  106. * Output parameters will appear here, with their values after the
  107. * stored procedure has been called.
  108. */
  109. public Map execute(final ParameterMapper inParamMapper) throws DataAccessException {
  110. return getJdbcTemplate().call(newCallableStatementCreator(inParamMapper), getDeclaredParameters());
  111. }
  112. }