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.sql.ResultSet;
  18. import org.springframework.dao.InvalidDataAccessApiUsageException;
  19. import org.springframework.jdbc.core.PreparedStatementCreator;
  20. import org.springframework.jdbc.core.PreparedStatementCreatorFactory;
  21. import org.springframework.jdbc.core.PreparedStatementSetter;
  22. import org.springframework.jdbc.support.JdbcUtils;
  23. /**
  24. * RdbmsOperation using a JdbcTemplate and representing a SQL-based
  25. * operation such as a query or update, as opposed to a stored procedure.
  26. *
  27. * <p>Configures a PreparedStatementCreatorFactory based on the
  28. * declared parameters.
  29. *
  30. * @author Rod Johnson
  31. * @author Juergen Hoeller
  32. * @version $Id: SqlOperation.java,v 1.11 2004/05/28 14:11:41 jhoeller Exp $
  33. */
  34. public abstract class SqlOperation extends RdbmsOperation {
  35. private int resultSetType = ResultSet.TYPE_FORWARD_ONLY;
  36. private boolean updatableResults = false;
  37. /**
  38. * Object enabling us to create PreparedStatementCreators
  39. * efficiently, based on this class's declared parameters.
  40. */
  41. private PreparedStatementCreatorFactory preparedStatementFactory;
  42. /**
  43. * Set whether to use prepared statements that return a
  44. * specific type of ResultSet.
  45. * @param resultSetType the ResultSet type
  46. * @see java.sql.ResultSet#TYPE_FORWARD_ONLY
  47. * @see java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE
  48. * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE
  49. */
  50. protected void setResultSetType(int resultSetType) {
  51. this.resultSetType = resultSetType;
  52. }
  53. /**
  54. * Return whether prepared statements will return a specific
  55. * type of ResultSet.
  56. */
  57. protected int getResultSetType() {
  58. return resultSetType;
  59. }
  60. /**
  61. * Set whether to use prepared statements capable of returning
  62. * updatable ResultSets.
  63. */
  64. protected void setUpdatableResults(boolean updatableResults) {
  65. this.updatableResults = updatableResults;
  66. }
  67. /**
  68. * Return whether prepared statements will return updatable ResultSets.
  69. */
  70. protected boolean isUpdatableResults() {
  71. return updatableResults;
  72. }
  73. /**
  74. * Overridden method to configure the PreparedStatementCreatorFactory
  75. * based on our declared parameters.
  76. */
  77. protected final void compileInternal() {
  78. // validate parameter count
  79. int bindVarCount = 0;
  80. try {
  81. bindVarCount = JdbcUtils.countParameterPlaceholders(getSql(), '?', '\'');
  82. }
  83. catch (IllegalArgumentException ex) {
  84. // transform JDBC-agnostic error to data access error
  85. throw new InvalidDataAccessApiUsageException(ex.getMessage());
  86. }
  87. if (bindVarCount != getDeclaredParameters().size())
  88. throw new InvalidDataAccessApiUsageException("SQL '" + getSql() + "' requires " + bindVarCount +
  89. " bind variables, but " + getDeclaredParameters().size() +
  90. " variables were declared for this object");
  91. this.preparedStatementFactory = new PreparedStatementCreatorFactory(getSql(), getDeclaredParameters());
  92. this.preparedStatementFactory.setResultSetType(this.resultSetType);
  93. this.preparedStatementFactory.setUpdatableResults(this.updatableResults);
  94. onCompileInternal();
  95. }
  96. /**
  97. * Hook method that subclasses may override to post-process compilation.
  98. * This implementation does nothing.
  99. * @see #compileInternal
  100. */
  101. protected void onCompileInternal() {
  102. }
  103. /**
  104. * Return a PreparedStatementCreator to perform an operation
  105. * with the given parameters.
  106. * @param params parameter array. May be null.
  107. */
  108. protected final PreparedStatementCreator newPreparedStatementCreator(Object[] params) {
  109. return this.preparedStatementFactory.newPreparedStatementCreator(params);
  110. }
  111. /**
  112. * Return a PreparedStatementSetter to perform an operation
  113. * with thhe given parameters.
  114. * @param params parameter array. May be null.
  115. */
  116. protected final PreparedStatementSetter newPreparedStatementSetter(Object[] params) {
  117. return this.preparedStatementFactory.newPreparedStatementSetter(params);
  118. }
  119. }