CallableStatementCreatorFactory.java
上传用户:jiancairen
上传日期:2007-08-27
资源大小:26458k
文件大小:8k
源码类别:

Java编程

开发平台:

Java

  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.core;
  17. import java.sql.CallableStatement;
  18. import java.sql.Connection;
  19. import java.sql.ResultSet;
  20. import java.sql.SQLException;
  21. import java.util.HashMap;
  22. import java.util.LinkedList;
  23. import java.util.List;
  24. import java.util.Map;
  25. import org.springframework.dao.InvalidDataAccessApiUsageException;
  26. import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
  27. /**
  28.  * Helper class that can efficiently create multiple CallableStatementCreator
  29.  * objects with different parameters based on a SQL statement and a single
  30.  * set of parameter declarations.
  31.  * @author Rod Johnson
  32.  * @author Thomas Risberg
  33.  * @author Juergen Hoeller
  34.  */
  35. public class CallableStatementCreatorFactory { 
  36. /** The SQL call string, which won't change when the parameters change. */
  37. private final String callString;
  38. /** List of SqlParameter objects. May not be null. */
  39. private final List declaredParameters;
  40. private int resultSetType = ResultSet.TYPE_FORWARD_ONLY;
  41. private boolean updatableResults = false;
  42. private NativeJdbcExtractor nativeJdbcExtractor;
  43. /**
  44.  * Create a new factory. Will need to add parameters
  45.  * via the addParameter() method or have no parameters.
  46.  */
  47. public CallableStatementCreatorFactory(String callString) {
  48. this.callString = callString;
  49. this.declaredParameters = new LinkedList();
  50. }
  51. /**
  52.  * Create a new factory with sql and the given parameters.
  53.  * @param callString the SQL call string
  54.  * @param declaredParameters list of SqlParameter objects
  55.  */
  56. public CallableStatementCreatorFactory(String callString, List declaredParameters) {
  57. this.callString = callString;
  58. this.declaredParameters = declaredParameters;
  59. }
  60. /**
  61.  * Add a new declared parameter.
  62.  * Order of parameter addition is significant.
  63.  */
  64. public void addParameter(SqlParameter param) {
  65. this.declaredParameters.add(param);
  66. }
  67. /**
  68.  * Set whether to use prepared statements that return a
  69.  * specific type of ResultSet.
  70.  * @param resultSetType the ResultSet type
  71.  * @see java.sql.ResultSet#TYPE_FORWARD_ONLY
  72.  * @see java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE
  73.  * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE
  74.  */
  75. public void setResultSetType(int resultSetType) {
  76. this.resultSetType = resultSetType;
  77. }
  78. /**
  79.  * Set whether to use prepared statements capable of returning
  80.  * updatable ResultSets.
  81.  */
  82. public void setUpdatableResults(boolean updatableResults) {
  83. this.updatableResults = updatableResults;
  84. }
  85. /**
  86.  * Specify the NativeJdbcExtractor to use for unwrapping
  87.  * CallableStatements, if any.
  88.  */
  89. public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
  90. this.nativeJdbcExtractor = nativeJdbcExtractor;
  91. }
  92. /**
  93.  * Return a new CallableStatementCreator instance given this parameters.
  94.  * @param inParams List of parameters. May be null.
  95.  */
  96. public CallableStatementCreator newCallableStatementCreator(Map inParams) {
  97. return new CallableStatementCreatorImpl(inParams != null ? inParams : new HashMap());
  98. }
  99. /**
  100.  * Return a new CallableStatementCreator instance given this parameter mapper.
  101.  * @param inParamMapper ParameterMapper implementation that will return a Map of parameters. May not be null.
  102.  */
  103. public CallableStatementCreator newCallableStatementCreator(ParameterMapper inParamMapper) {
  104. return new CallableStatementCreatorImpl(inParamMapper);
  105. }
  106. /**
  107.  * CallableStatementCreator implementation returned by this class.
  108.  */
  109. private class CallableStatementCreatorImpl
  110. implements CallableStatementCreator, SqlProvider, ParameterDisposer {
  111. private final ParameterMapper inParameterMapper;
  112. private Map inParameters;
  113. /**
  114.  * Create a new CallableStatementCreatorImpl.
  115.  * @param inParams list of SqlParameter objects. May not be null.
  116.  */
  117. public CallableStatementCreatorImpl(Map inParams) {
  118. this.inParameterMapper = null;
  119. this.inParameters = inParams;
  120. }
  121. /**
  122.  * Create a new CallableStatementCreatorImpl.
  123.  * @param inParamMapper ParameterMapper implementation for mapping input parameters.
  124.  * May not be null.
  125.  */
  126. public CallableStatementCreatorImpl(ParameterMapper inParamMapper) {
  127. this.inParameterMapper = inParamMapper;
  128. this.inParameters = null;
  129. }
  130. public CallableStatement createCallableStatement(Connection con) throws SQLException {
  131. // If we were given a ParameterMapper - we must let the mapper do its thing to create the Map.
  132. if (this.inParameterMapper != null) {
  133. this.inParameters = this.inParameterMapper.createMap(con);
  134. }
  135. else {
  136. if (this.inParameters == null) {
  137. throw new InvalidDataAccessApiUsageException("A ParameterMapper or a Map of parameters must be provided");
  138. }
  139. }
  140. CallableStatement cs = null;
  141. if (resultSetType == ResultSet.TYPE_FORWARD_ONLY && !updatableResults) {
  142. cs = con.prepareCall(callString);
  143. }
  144. else {
  145. cs = con.prepareCall(callString, resultSetType,
  146.  updatableResults ? ResultSet.CONCUR_UPDATABLE : ResultSet.CONCUR_READ_ONLY);
  147. }
  148. // determine CallabeStatement to pass to custom types
  149. CallableStatement csToUse = cs;
  150. if (nativeJdbcExtractor != null) {
  151. csToUse = nativeJdbcExtractor.getNativeCallableStatement(cs);
  152. }
  153. int sqlColIndx = 1;
  154. for (int i = 0; i < declaredParameters.size(); i++) {
  155. SqlParameter declaredParameter = (SqlParameter) declaredParameters.get(i);
  156. if (!this.inParameters.containsKey(declaredParameter.getName()) &&
  157. !(declaredParameter instanceof SqlOutParameter) && 
  158. !(declaredParameter instanceof SqlReturnResultSet)) {
  159. throw new InvalidDataAccessApiUsageException("Required input parameter '" + declaredParameter.getName() + "' is missing");
  160. }
  161. // the value may still be null
  162. Object inValue = this.inParameters.get(declaredParameter.getName());
  163. if (!(declaredParameter instanceof SqlOutParameter) && !(declaredParameter instanceof SqlReturnResultSet)) {
  164. StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx, declaredParameter, inValue);
  165. }
  166. else {
  167. // It's an output parameter. Skip SqlReturnResultSet parameters
  168. // It need not (but may be) supplied by the caller.
  169. if (declaredParameter instanceof SqlOutParameter) {
  170. if (declaredParameter.getTypeName() != null) {
  171. cs.registerOutParameter(sqlColIndx, declaredParameter.getSqlType(), declaredParameter.getTypeName());
  172. }
  173. else {
  174. cs.registerOutParameter(sqlColIndx, declaredParameter.getSqlType());
  175. }
  176. if (inValue != null) {
  177. StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx, declaredParameter, inValue);
  178. }
  179. }
  180. }
  181. if (!(declaredParameter instanceof SqlReturnResultSet)) {
  182. sqlColIndx++;
  183. }
  184. }
  185. return cs;
  186. }
  187. public String getSql() {
  188. return callString;
  189. }
  190. public void cleanupParameters() {
  191. StatementCreatorUtils.cleanupParameters(this.inParameters.values());
  192. }
  193. public String toString() {
  194. StringBuffer buf = new StringBuffer("CallableStatementCreatorFactory.CallableStatementCreatorImpl: sql=[");
  195. buf.append(callString);
  196. buf.append("]: params=[");
  197. if (inParameters != null) {
  198. buf.append(inParameters.toString());
  199. }
  200. buf.append(']');
  201. return buf.toString();
  202. }
  203. }
  204. }