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 javax.sql.DataSource;
  18. import org.springframework.dao.DataAccessException;
  19. import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException;
  20. /**
  21. * RdbmsOperation subclass representing a SQL update.
  22. * Like a query, an update object is reusable. Like all RdbmsOperation
  23. * objects, an update can have parameters and is defined in SQL.
  24. *
  25. * <p>This class provides a number of update() methods analogous to the
  26. * execute() methods of query objects.
  27. *
  28. * <p>This class is concrete. Although it can be subclassed (for example
  29. * to add a custom update method) it can easily be parameterized by setting
  30. * SQL and declaring parameters.
  31. *
  32. * @author Rod Johnson
  33. * @author Isabelle Muszynski
  34. * @version $Id: SqlUpdate.java,v 1.8 2004/05/29 21:20:23 jhoeller Exp $
  35. */
  36. public class SqlUpdate extends SqlOperation {
  37. /**
  38. * Maximum number of rows the update may affect. If more are
  39. * affected, an exception will be thrown. Ignored if 0.
  40. */
  41. private int maxRowsAffected = 0;
  42. /**
  43. * An exact number of rows that must be affected.
  44. * Ignored if 0.
  45. */
  46. private int requiredRowsAffected = 0;
  47. /**
  48. * Constructor to allow use as a JavaBean. DataSource and SQL
  49. * must be supplied before compilation and use.
  50. */
  51. public SqlUpdate() {
  52. }
  53. /**
  54. * Constructs an update object with a given DataSource and SQL.
  55. * @param ds DataSource to use to obtain connections
  56. * @param sql SQL statement to execute
  57. */
  58. public SqlUpdate(DataSource ds, String sql) {
  59. setDataSource(ds);
  60. setSql(sql);
  61. }
  62. /**
  63. * Construct an update object with a given DataSource, SQL
  64. * and anonymous parameters.
  65. * @param ds DataSource to use to obtain connections
  66. * @param sql SQL statement to execute
  67. * @param types anonymous parameter declarations
  68. */
  69. public SqlUpdate(DataSource ds, String sql, int[] types) {
  70. setDataSource(ds);
  71. setSql(sql);
  72. setTypes(types);
  73. }
  74. /**
  75. * Construct an update object with a given DataSource, SQL,
  76. * anonymous parameters and specifying the maximum number of rows
  77. * that may be affected.
  78. * @param ds DataSource to use to obtain connections
  79. * @param sql SQL statement to execute
  80. * @param types anonymous parameter declarations.
  81. * @param maxRowsAffected the maximum number of rows that may
  82. * be affected by the update
  83. */
  84. public SqlUpdate(DataSource ds, String sql, int[] types, int maxRowsAffected) {
  85. setDataSource(ds);
  86. setSql(sql);
  87. setTypes(types);
  88. this.maxRowsAffected = maxRowsAffected;
  89. }
  90. /**
  91. * Set the maximum number of rows that may be affected by this update.
  92. * The default value is 0, which does not limit the number of rows affected.
  93. * @param maxRowsAffected the maximum number of rows that can be affected by
  94. * this update without this class's update method considering it an error
  95. */
  96. public void setMaxRowsAffected(int maxRowsAffected) {
  97. this.maxRowsAffected = maxRowsAffected;
  98. }
  99. /**
  100. * Set the <i>exact</i> number of rows that must be affected by this update.
  101. * The default value is 0, which allows any number of rows to be affected.
  102. * <p>This is an alternative to setting the <i>maximum</i> number of rows
  103. * that may be affected.
  104. * @param requiredRowsAffected the exact number of rows that must be affected
  105. * by this update without this class's update method considering it an error
  106. */
  107. public void setRequiredRowsAffected(int requiredRowsAffected) {
  108. this.requiredRowsAffected = requiredRowsAffected;
  109. }
  110. /**
  111. * Check the given number of affected rows against the
  112. * specified maximum number respectively required number.
  113. * @param rowsAffected the number of affected rows
  114. * @throws JdbcUpdateAffectedIncorrectNumberOfRowsException
  115. * if the actually affected rows are out of bounds
  116. * @see #setMaxRowsAffected
  117. * @see #setRequiredRowsAffected
  118. */
  119. protected void checkRowsAffected(int rowsAffected) throws JdbcUpdateAffectedIncorrectNumberOfRowsException {
  120. if (this.maxRowsAffected > 0 && rowsAffected > this.maxRowsAffected) {
  121. throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(getSql(), this.maxRowsAffected, rowsAffected);
  122. }
  123. if (this.requiredRowsAffected > 0 && rowsAffected != this.requiredRowsAffected) {
  124. throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(getSql(), this.requiredRowsAffected, rowsAffected);
  125. }
  126. }
  127. /**
  128. * Generic method to execute the update given arguments.
  129. * All other update methods invoke this method.
  130. * @param args array of object arguments
  131. * @return the number of rows affected by the update
  132. */
  133. public int update(Object[] args) throws DataAccessException {
  134. validateParameters(args);
  135. int rowsAffected = getJdbcTemplate().update(newPreparedStatementCreator(args));
  136. checkRowsAffected(rowsAffected);
  137. return rowsAffected;
  138. }
  139. /**
  140. * Convenience method to execute an update with no parameters.
  141. */
  142. public int update() throws DataAccessException {
  143. return update((Object[]) null);
  144. }
  145. /**
  146. * Convenient method to execute an update given one int arg.
  147. */
  148. public int update(int p1) throws DataAccessException {
  149. return update(new Object[] {new Integer(p1)});
  150. }
  151. /**
  152. * Convenient method to execute an update given two int args.
  153. */
  154. public int update(int p1, int p2) throws DataAccessException {
  155. return update(new Object[] {new Integer(p1), new Integer(p2)});
  156. }
  157. /**
  158. * Convenient method to execute an update given one long arg.
  159. */
  160. public int update(long p1) throws DataAccessException {
  161. return update(new Object[] {new Long(p1)});
  162. }
  163. /**
  164. * Convenient method to execute an update given two long args.
  165. */
  166. public int update(long p1, long p2) throws DataAccessException {
  167. return update(new Object[] {new Long(p1), new Long(p2)});
  168. }
  169. /**
  170. * Convenient method to execute an update given one String arg.
  171. */
  172. public int update(String p) throws DataAccessException {
  173. return update(new Object[] {p});
  174. }
  175. /**
  176. * Convenient method to execute an update given two String args.
  177. */
  178. public int update(String p1, String p2) throws DataAccessException {
  179. return update(new Object[] {p1, p2});
  180. }
  181. }