PreparedStatementCreatorFactory.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.Connection;
  18. import java.sql.PreparedStatement;
  19. import java.sql.ResultSet;
  20. import java.sql.SQLException;
  21. import java.util.Arrays;
  22. import java.util.Collections;
  23. import java.util.LinkedList;
  24. import java.util.List;
  25. import org.springframework.dao.InvalidDataAccessApiUsageException;
  26. import org.springframework.dao.InvalidDataAccessResourceUsageException;
  27. import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
  28. /**
  29.  * Helper class that can efficiently create multiple PreparedStatementCreator
  30.  * objects with different parameters based on a SQL statement and a single
  31.  * set of parameter declarations.
  32.  * @author Rod Johnson
  33.  * @author Juergen Hoeller
  34.  */
  35. public class PreparedStatementCreatorFactory {
  36. /** The SQL, which won't change when the parameters change */
  37. private final String sql;
  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 boolean returnGeneratedKeys = false;
  43. private String[] generatedKeysColumnNames = null;
  44. private NativeJdbcExtractor nativeJdbcExtractor;
  45. /**
  46.  * Create a new factory. Will need to add parameters
  47.  * via the addParameter() method or have no parameters.
  48.  */
  49. public PreparedStatementCreatorFactory(String sql) {
  50. this.sql = sql;
  51. this.declaredParameters = new LinkedList();
  52. }
  53. /**
  54.  * Create a new factory with the given SQL and JDBC types.
  55.  * @param sql SQL to execute
  56.  * @param types int array of JDBC types
  57.  */
  58. public PreparedStatementCreatorFactory(String sql, int[] types) {
  59. this.sql = sql;
  60. this.declaredParameters = SqlParameter.sqlTypesToAnonymousParameterList(types);
  61. }
  62. /**
  63.  * Create a new factory with the given SQL and parameters.
  64.  * @param sql SQL
  65.  * @param declaredParameters list of SqlParameter objects
  66.  * @see SqlParameter
  67.  */
  68. public PreparedStatementCreatorFactory(String sql, List declaredParameters) {
  69. this.sql = sql;
  70. this.declaredParameters = declaredParameters;
  71. }
  72. /**
  73.  * Add a new declared parameter.
  74.  * Order of parameter addition is significant.
  75.  */
  76. public void addParameter(SqlParameter param) {
  77. this.declaredParameters.add(param);
  78. }
  79. /**
  80.  * Set whether to use prepared statements that return a
  81.  * specific type of ResultSet.
  82.  * @param resultSetType the ResultSet type
  83.  * @see java.sql.ResultSet#TYPE_FORWARD_ONLY
  84.  * @see java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE
  85.  * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE
  86.  */
  87. public void setResultSetType(int resultSetType) {
  88. this.resultSetType = resultSetType;
  89. }
  90. /**
  91.  * Set whether to use prepared statements capable of returning
  92.  * updatable ResultSets.
  93.  * @param updatableResults Set to true for an updatable ResultSet.
  94.  */
  95. public void setUpdatableResults(boolean updatableResults) {
  96. this.updatableResults = updatableResults;
  97. }
  98. /**
  99.  * Set whether prepared statements should be capable of returning
  100.  * auto-generated keys.
  101.  */
  102. public void setReturnGeneratedKeys(boolean returnGeneratedKeys) {
  103. this.returnGeneratedKeys = returnGeneratedKeys;
  104. }
  105. /**
  106.  * Set the column names of the auto-generated keys.
  107.  */
  108. public void setGeneratedKeysColumnNames(String[] names) {
  109. this.generatedKeysColumnNames = names;
  110. }
  111. /**
  112.  * Specify the NativeJdbcExtractor to use for unwrapping
  113.  * PreparedStatements, if any.
  114.  */
  115. public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
  116. this.nativeJdbcExtractor = nativeJdbcExtractor;
  117. }
  118. /**
  119.  * Return a new PreparedStatementCreator for the given parameters.
  120.  * @param params parameter array. May be null.
  121.  */
  122. public PreparedStatementCreator newPreparedStatementCreator(Object[] params) {
  123. return new PreparedStatementCreatorImpl((params != null) ? Arrays.asList(params) : Collections.EMPTY_LIST);
  124. }
  125. /**
  126.  * Return a new PreparedStatementCreator for the given parameters.
  127.  * @param params List of parameters. May be null.
  128.  */
  129. public PreparedStatementCreator newPreparedStatementCreator(List params) {
  130. return new PreparedStatementCreatorImpl(params != null ? params : Collections.EMPTY_LIST);
  131. }
  132. /**
  133.  * Return a new PreparedStatementSetter for the given parameters.
  134.  * @param params parameter array. May be null.
  135.  */
  136. public PreparedStatementSetter newPreparedStatementSetter(Object[] params) {
  137. return new PreparedStatementCreatorImpl((params != null) ? Arrays.asList(params) : Collections.EMPTY_LIST);
  138. }
  139. /**
  140.  * Return a new PreparedStatementSetter for the given parameters.
  141.  * @param params List of parameters. May be null.
  142.  */
  143. public PreparedStatementSetter newPreparedStatementSetter(List params) {
  144. return new PreparedStatementCreatorImpl(params != null ? params : Collections.EMPTY_LIST);
  145. }
  146. /**
  147.  * PreparedStatementCreator implementation returned by this class.
  148.  */
  149. private class PreparedStatementCreatorImpl
  150. implements PreparedStatementCreator, PreparedStatementSetter, SqlProvider, ParameterDisposer {
  151. private final List parameters;
  152. /**
  153.  * Create a new PreparedStatementCreatorImpl.
  154.  * @param parameters list of parameter objects
  155.  */
  156. public PreparedStatementCreatorImpl(List parameters) {
  157. this.parameters = parameters;
  158. if (this.parameters.size() != declaredParameters.size())
  159. throw new InvalidDataAccessApiUsageException("SQL=[" + sql + "]: given " + this.parameters.size() +
  160.                                              " parameter but expected " + declaredParameters.size());
  161. }
  162. public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
  163. PreparedStatement ps = null;
  164. if (returnGeneratedKeys) {
  165. try {
  166. if (generatedKeysColumnNames == null) {
  167. ps = con.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
  168. }
  169. else {
  170. ps = con.prepareStatement(sql, generatedKeysColumnNames);
  171. }
  172. }
  173. catch (AbstractMethodError ex) {
  174. throw new InvalidDataAccessResourceUsageException("The JDBC driver is not compliant to JDBC 3.0 and thus " +
  175. "does not support retrieval of auto generated keys", ex);
  176. }
  177. }
  178. else if (resultSetType == ResultSet.TYPE_FORWARD_ONLY && !updatableResults) {
  179. ps = con.prepareStatement(sql);
  180. }
  181. else {
  182. ps = con.prepareStatement(sql, resultSetType,
  183. updatableResults ? ResultSet.CONCUR_UPDATABLE : ResultSet.CONCUR_READ_ONLY);
  184. }
  185. setValues(ps);
  186. return ps;
  187. }
  188. public void setValues(PreparedStatement ps) throws SQLException {
  189. // determine PreparedStatement to pass to custom types
  190. PreparedStatement psToUse = ps;
  191. if (nativeJdbcExtractor != null) {
  192. psToUse = nativeJdbcExtractor.getNativePreparedStatement(ps);
  193. }
  194. // Set arguments: Does nothing if there are no parameters.
  195. for (int i = 0; i < this.parameters.size(); i++) {
  196. SqlParameter declaredParameter = (SqlParameter) declaredParameters.get(i);
  197. Object in = this.parameters.get(i);
  198. int sqlColIndx = i + 1;
  199. StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx, declaredParameter, in);
  200. }
  201. }
  202. public String getSql() {
  203. return sql;
  204. }
  205. public void cleanupParameters() {
  206. StatementCreatorUtils.cleanupParameters(this.parameters);
  207. }
  208. public String toString() {
  209. StringBuffer buf = new StringBuffer("PreparedStatementCreatorFactory.PreparedStatementCreatorImpl: sql=[");
  210. buf.append(sql);
  211. buf.append("]: params=[");
  212. for (int i = 0; i < this.parameters.size(); i++) {
  213. if (i > 0) {
  214. buf.append(',');
  215. }
  216. buf.append(this.parameters.get(i));
  217. }
  218. return buf.toString() + "]";
  219. }
  220. }
  221. }