001: /*
002: * Copyright 2002-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.jdbc.object;
018:
019: import java.util.Map;
020:
021: import javax.sql.DataSource;
022:
023: import org.springframework.dao.DataAccessException;
024: import org.springframework.dao.InvalidDataAccessApiUsageException;
025: import org.springframework.jdbc.core.JdbcTemplate;
026: import org.springframework.jdbc.core.ParameterMapper;
027: import org.springframework.jdbc.core.SqlParameter;
028:
029: /**
030: * Superclass for object abstractions of RDBMS stored procedures.
031: * This class is abstract and it is intended that subclasses will provide
032: * a typed method for invocation that delegates to the supplied
033: * {@link #execute} method.
034: *
035: * <p>The inherited <code>sql</code> property is the name of the stored
036: * procedure in the RDBMS. Note that JDBC 3.0 introduces named parameters,
037: * although the other features provided by this class are still necessary
038: * in JDBC 3.0.
039: *
040: * @author Rod Johnson
041: * @author Thomas Risberg
042: * @see #setSql
043: */
044: public abstract class StoredProcedure extends SqlCall {
045:
046: /**
047: * Allow use as a bean.
048: */
049: protected StoredProcedure() {
050: }
051:
052: /**
053: * Create a new object wrapper for a stored procedure.
054: * @param ds DataSource to use throughout the lifetime
055: * of this object to obtain connections
056: * @param name name of the stored procedure in the database
057: */
058: protected StoredProcedure(DataSource ds, String name) {
059: setDataSource(ds);
060: setSql(name);
061: }
062:
063: /**
064: * Create a new object wrapper for a stored procedure.
065: * @param jdbcTemplate JdbcTemplate which wraps DataSource
066: * @param name name of the stored procedure in the database
067: */
068: protected StoredProcedure(JdbcTemplate jdbcTemplate, String name) {
069: setJdbcTemplate(jdbcTemplate);
070: setSql(name);
071: }
072:
073: /**
074: * StoredProcedure parameter Maps are by default allowed to contain
075: * additional entries that are not actually used as parameters.
076: */
077: protected boolean allowsUnusedParameters() {
078: return true;
079: }
080:
081: /**
082: * Declare a parameter. Overridden method.
083: * <b>Note: Calls to declareParameter must be made in the same order as
084: * they appear in the database's stored procedure parameter list.</b>
085: * Names are purely used to help mapping.
086: * @param param parameter object
087: */
088: public void declareParameter(SqlParameter param)
089: throws InvalidDataAccessApiUsageException {
090: if (param.getName() == null) {
091: throw new InvalidDataAccessApiUsageException(
092: "Parameters to stored procedures must have names as well as types");
093: }
094: super .declareParameter(param);
095: }
096:
097: /**
098: * Execute the stored procedure. Subclasses should define a strongly typed
099: * execute method (with a meaningful name) that invokes this method, populating
100: * the input map and extracting typed values from the output map. Subclass
101: * execute methods will often take domain objects as arguments and return values.
102: * Alternatively, they can return void.
103: * @param inParams map of input parameters, keyed by name as in parameter
104: * declarations. Output parameters need not (but can be) included in this map.
105: * It is legal for map entries to be <code>null</code>, and this will produce the
106: * correct behavior using a NULL argument to the stored procedure.
107: * @return map of output params, keyed by name as in parameter declarations.
108: * Output parameters will appear here, with their values after the
109: * stored procedure has been called.
110: */
111: public Map execute(Map inParams) throws DataAccessException {
112: validateParameters(inParams.values().toArray());
113: return getJdbcTemplate().call(
114: newCallableStatementCreator(inParams),
115: getDeclaredParameters());
116: }
117:
118: /**
119: * Execute the stored procedure. Subclasses should define a strongly typed
120: * execute method (with a meaningful name) that invokes this method, passing in
121: * a ParameterMapper that will populate the input map. This allows mapping database
122: * specific features since the ParameterMapper has access to the Connection object.
123: * The execute method is also responsible for extracting typed values from the output map.
124: * Subclass execute methods will often take domain objects as arguments and return values.
125: * Alternatively, they can return void.
126: * @param inParamMapper map of input parameters, keyed by name as in parameter
127: * declarations. Output parameters need not (but can be) included in this map.
128: * It is legal for map entries to be <code>null</code>, and this will produce the correct
129: * behavior using a NULL argument to the stored procedure.
130: * @return map of output params, keyed by name as in parameter declarations.
131: * Output parameters will appear here, with their values after the
132: * stored procedure has been called.
133: */
134: public Map execute(ParameterMapper inParamMapper)
135: throws DataAccessException {
136: checkCompiled();
137: return getJdbcTemplate().call(
138: newCallableStatementCreator(inParamMapper),
139: getDeclaredParameters());
140: }
141:
142: }
|